From 759b7ec94e71dcf11a385c4cfa91e6683d6cf2f9 Mon Sep 17 00:00:00 2001 From: Aravind Krishna Date: Thu, 21 May 2026 14:43:36 +0530 Subject: [PATCH] adding vdevice tests --- Tests/vDeviceTests/HdmiCecSourceApis.py | 138 ++++++ Tests/vDeviceTests/README.txt.txt | 19 + Tests/vDeviceTests/TCID001.py | 44 ++ Tests/vDeviceTests/TCID002.py | 86 ++++ Tests/vDeviceTests/TCID003.py | 45 ++ Tests/vDeviceTests/TCID004.py | 45 ++ Tests/vDeviceTests/TCID005.py | 45 ++ Tests/vDeviceTests/TCID006.py | 46 ++ Tests/vDeviceTests/TCID007.py | 44 ++ Tests/vDeviceTests/TCID008.py | 50 +++ Tests/vDeviceTests/TCID009.py | 44 ++ Tests/vDeviceTests/TCID010.py | 44 ++ Tests/vDeviceTests/TCID011.py | 44 ++ Tests/vDeviceTests/TCID012.py | 45 ++ Tests/vDeviceTests/TCID013.py | 44 ++ Tests/vDeviceTests/TCID014.py | 45 ++ Tests/vDeviceTests/TCID015.py | 45 ++ Tests/vDeviceTests/TCID016.py | 56 +++ Tests/vDeviceTests/TCID018.py | 96 +++++ Tests/vDeviceTests/TCID019.py | 107 +++++ Tests/vDeviceTests/TCID020.py | 95 +++++ Tests/vDeviceTests/TCID021.py | 123 ++++++ Tests/vDeviceTests/TCID022.py | 96 +++++ Tests/vDeviceTests/TCID023.py | 121 ++++++ Tests/vDeviceTests/TCID024.py | 104 +++++ .../HdmiCecSourceApis.cpython-312.pyc | Bin 0 -> 3378 bytes .../__pycache__/TCID001.cpython-312.pyc | Bin 0 -> 1347 bytes .../__pycache__/TCID002.cpython-312.pyc | Bin 0 -> 2185 bytes .../__pycache__/TCID003.cpython-312.pyc | Bin 0 -> 1357 bytes .../__pycache__/TCID004.cpython-312.pyc | Bin 0 -> 1374 bytes .../__pycache__/TCID005.cpython-312.pyc | Bin 0 -> 1355 bytes .../__pycache__/TCID006.cpython-312.pyc | Bin 0 -> 1429 bytes .../__pycache__/TCID007.cpython-312.pyc | Bin 0 -> 1347 bytes .../__pycache__/TCID008.cpython-312.pyc | Bin 0 -> 1685 bytes .../__pycache__/TCID009.cpython-312.pyc | Bin 0 -> 1346 bytes .../__pycache__/TCID010.cpython-312.pyc | Bin 0 -> 1331 bytes .../__pycache__/TCID011.cpython-312.pyc | Bin 0 -> 1349 bytes .../__pycache__/TCID012.cpython-312.pyc | Bin 0 -> 1347 bytes .../__pycache__/TCID013.cpython-312.pyc | Bin 0 -> 1333 bytes .../__pycache__/TCID014.cpython-312.pyc | Bin 0 -> 1355 bytes .../__pycache__/TCID018.cpython-312.pyc | Bin 0 -> 3322 bytes .../__pycache__/TCID019.cpython-312.pyc | Bin 0 -> 3523 bytes .../__pycache__/TCID020.cpython-312.pyc | Bin 0 -> 3100 bytes .../__pycache__/TCID021.cpython-312.pyc | Bin 0 -> 4191 bytes .../__pycache__/TCID022.cpython-312.pyc | Bin 0 -> 3393 bytes .../__pycache__/TCID023.cpython-312.pyc | Bin 0 -> 4528 bytes .../__pycache__/TCID024.cpython-312.pyc | Bin 0 -> 3812 bytes .../__pycache__/suiteManager.cpython-312.pyc | Bin 0 -> 5046 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 2043 bytes .../vDeviceTests/hdmiCec_vcomponent_design.md | 392 ++++++++++++++++++ .../ledIndicator/TCID001_indicator.py | 45 ++ .../ledIndicator/TCID002_indicator.py | 47 +++ .../ledIndicator/TCID003_indicator.py | 45 ++ .../ledIndicator/TCID004_indicator.py | 73 ++++ .../TCID001_indicator.cpython-312.pyc | Bin 0 -> 1460 bytes .../TCID002_indicator.cpython-312.pyc | Bin 0 -> 1772 bytes .../TCID003_indicator.cpython-312.pyc | Bin 0 -> 1603 bytes .../TCID004_indicator.cpython-312.pyc | Bin 0 -> 3087 bytes .../ledIndicatorApis.cpython-312.pyc | Bin 0 -> 872 bytes .../ledIndicator/ledIndicatorApis.py | 23 + Tests/vDeviceTests/suiteManager.py | 139 +++++++ Tests/vDeviceTests/utils.py | 55 +++ 62 files changed, 2490 insertions(+) create mode 100644 Tests/vDeviceTests/HdmiCecSourceApis.py create mode 100644 Tests/vDeviceTests/README.txt.txt create mode 100644 Tests/vDeviceTests/TCID001.py create mode 100644 Tests/vDeviceTests/TCID002.py create mode 100644 Tests/vDeviceTests/TCID003.py create mode 100644 Tests/vDeviceTests/TCID004.py create mode 100644 Tests/vDeviceTests/TCID005.py create mode 100644 Tests/vDeviceTests/TCID006.py create mode 100644 Tests/vDeviceTests/TCID007.py create mode 100644 Tests/vDeviceTests/TCID008.py create mode 100644 Tests/vDeviceTests/TCID009.py create mode 100644 Tests/vDeviceTests/TCID010.py create mode 100644 Tests/vDeviceTests/TCID011.py create mode 100644 Tests/vDeviceTests/TCID012.py create mode 100644 Tests/vDeviceTests/TCID013.py create mode 100644 Tests/vDeviceTests/TCID014.py create mode 100644 Tests/vDeviceTests/TCID015.py create mode 100644 Tests/vDeviceTests/TCID016.py create mode 100644 Tests/vDeviceTests/TCID018.py create mode 100644 Tests/vDeviceTests/TCID019.py create mode 100644 Tests/vDeviceTests/TCID020.py create mode 100644 Tests/vDeviceTests/TCID021.py create mode 100644 Tests/vDeviceTests/TCID022.py create mode 100644 Tests/vDeviceTests/TCID023.py create mode 100644 Tests/vDeviceTests/TCID024.py create mode 100644 Tests/vDeviceTests/__pycache__/HdmiCecSourceApis.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID004.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID005.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID006.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID011.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID013.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc create mode 100644 Tests/vDeviceTests/__pycache__/utils.cpython-312.pyc create mode 100644 Tests/vDeviceTests/hdmiCec_vcomponent_design.md create mode 100644 Tests/vDeviceTests/ledIndicator/TCID001_indicator.py create mode 100644 Tests/vDeviceTests/ledIndicator/TCID002_indicator.py create mode 100644 Tests/vDeviceTests/ledIndicator/TCID003_indicator.py create mode 100644 Tests/vDeviceTests/ledIndicator/TCID004_indicator.py create mode 100644 Tests/vDeviceTests/ledIndicator/__pycache__/TCID001_indicator.cpython-312.pyc create mode 100644 Tests/vDeviceTests/ledIndicator/__pycache__/TCID002_indicator.cpython-312.pyc create mode 100644 Tests/vDeviceTests/ledIndicator/__pycache__/TCID003_indicator.cpython-312.pyc create mode 100644 Tests/vDeviceTests/ledIndicator/__pycache__/TCID004_indicator.cpython-312.pyc create mode 100644 Tests/vDeviceTests/ledIndicator/__pycache__/ledIndicatorApis.cpython-312.pyc create mode 100644 Tests/vDeviceTests/ledIndicator/ledIndicatorApis.py create mode 100644 Tests/vDeviceTests/suiteManager.py create mode 100644 Tests/vDeviceTests/utils.py diff --git a/Tests/vDeviceTests/HdmiCecSourceApis.py b/Tests/vDeviceTests/HdmiCecSourceApis.py new file mode 100644 index 00000000..5a1fdd36 --- /dev/null +++ b/Tests/vDeviceTests/HdmiCecSourceApis.py @@ -0,0 +1,138 @@ +send_standby_message = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.sendStandbyMessage"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +get_device_list = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.getDeviceList"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +get_enabled = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.getEnabled"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +get_osd_name = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.getOSDName"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +get_otp_enabled = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.getOTPEnabled"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +get_vendor_id = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.getVendorId"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + + +perform_otp_action = ( + 'curl --max-time 8 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,"method":"org.rdk.HdmiCecSource.performOTPAction"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +send_key_press_event = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.sendKeyPressEvent",' + '"params":{"logicalAddress":0,"keyCode":65}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +set_enabled_false = ( + 'curl --max-time 8 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setEnabled",' + '"params":{"enabled":false}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +set_enabled_true = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setEnabled",' + '"params":{"enabled":true}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + +set_osd_name = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setOSDName",' + '"params":{"name":"Sky TV"}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +set_otp_enabled_true = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setOTPEnabled",' + '"params":{"enabled":true}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +set_vendor_id = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setVendorId",' + '"params":{"vendorid":"0x0019FB"}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + + +set_otp_enabled_false = ( + 'curl --max-time 5 ' + '--header "Content-Type: application/json" ' + '--request POST ' + '-d \'{"jsonrpc":"2.0","id":42,' + '"method":"org.rdk.HdmiCecSource.setOTPEnabled",' + '"params":{"enabled":false}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) diff --git a/Tests/vDeviceTests/README.txt.txt b/Tests/vDeviceTests/README.txt.txt new file mode 100644 index 00000000..5c2ae107 --- /dev/null +++ b/Tests/vDeviceTests/README.txt.txt @@ -0,0 +1,19 @@ +To execute the cases inside qemu + +cd /tmp + +git clone git@github.com:rdkcentral/entservices-inputoutput.git + +cd entservices-inputoutput/vDeviceTests + +python3 suiteManager.py Hdmicecsource # to execute hdmicecsource testcases + + +python3 suiteManager.py ledindicator + + +errors incase if any:- + +hdmicec_post_command.sh not found - +here in the testcases add the path where hdmicec_post_command.sh script is present inside the qemu +for eg tmp/vDeviceTests/vHdmiCec/vComponent_configurations/hdmicec_post_command.sh \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID001.py b/Tests/vDeviceTests/TCID001.py new file mode 100644 index 00000000..dedc6fb8 --- /dev/null +++ b/Tests/vDeviceTests/TCID001.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command send standby message") + + curl_response = send_curl_command( + HdmiCecSourceApis.send_standby_message + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID001 Passed ✅") + return True + else: + log_error("TCID001 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID001 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID002.py b/Tests/vDeviceTests/TCID002.py new file mode 100644 index 00000000..a4d57b93 --- /dev/null +++ b/Tests/vDeviceTests/TCID002.py @@ -0,0 +1,86 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "numberofdevices": 5, + "deviceList": [ + { + "logicalAddress": 1, + "vendorID": "0099", + "osdName": "CECAdapter" + }, + { + "logicalAddress": 4, + "vendorID": "0e036", + "osdName": "PIONEER" + }, + { + "logicalAddress": 5, + "vendorID": "0a0de", + "osdName": "YAMAHA" + }, + { + "logicalAddress": 6, + "vendorID": "01a11", + "osdName": "GOOGLE" + }, + { + "logicalAddress": 7, + "vendorID": "00a1", + "osdName": "IPSTB" + }, + { + "logicalAddress": 8, + "vendorID": "000", + "osdName": "Kishore" + } + ], + "success": True + } + } + log_info("Executing the curl command get device list") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + actual_output_response = json.loads(curl_response) + expected_normalized = json.dumps(expected_output_response, sort_keys=True) + actual_normalized = json.dumps(actual_output_response, sort_keys=True) + + if actual_normalized == expected_normalized: + log_success("TCID002 Passed ✅") + return True + else: + log_warning( + f"Expected: {json.dumps(expected_output_response, indent=2, sort_keys=True)}" + ) + log_warning( + f"Actual : {json.dumps(actual_output_response, indent=2, sort_keys=True)}" + ) + log_error("TCID002 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID002 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID003.py b/Tests/vDeviceTests/TCID003.py new file mode 100644 index 00000000..6f948fe4 --- /dev/null +++ b/Tests/vDeviceTests/TCID003.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "enabled": True, + "success": True + } + } + + log_info("Executing the curl command get enabled Driver status") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_enabled + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID003 Passed ✅") + return True + else: + log_error("TCID003 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID003 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID004.py b/Tests/vDeviceTests/TCID004.py new file mode 100644 index 00000000..bec81afc --- /dev/null +++ b/Tests/vDeviceTests/TCID004.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "enabled": True, + "success": True + } + } + + log_info("Executing the curl command get OTP enabled") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_otp_enabled + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID004 Passed ✅") + return True + else: + log_error("TCID004 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID001 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID005.py b/Tests/vDeviceTests/TCID005.py new file mode 100644 index 00000000..103d53ce --- /dev/null +++ b/Tests/vDeviceTests/TCID005.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "vendorid": "019fb", + "success": True + } + } + + log_info("Executing the curl command get vendor ID") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_vendor_id + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID005 Passed ✅") + return True + else: + log_error("TCID005 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID005 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID006.py b/Tests/vDeviceTests/TCID006.py new file mode 100644 index 00000000..f0b3e333 --- /dev/null +++ b/Tests/vDeviceTests/TCID006.py @@ -0,0 +1,46 @@ +import json, time +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command perform OTP Action") + + + time.sleep(3) + curl_response = send_curl_command( + HdmiCecSourceApis.perform_otp_action + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID006 Passed ✅") + return True + else: + log_error("TCID006 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID006 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID007.py b/Tests/vDeviceTests/TCID007.py new file mode 100644 index 00000000..bb0e5d3a --- /dev/null +++ b/Tests/vDeviceTests/TCID007.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command send key press event") + + curl_response = send_curl_command( + HdmiCecSourceApis.send_key_press_event + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID007 Passed ✅") + return True + else: + log_error("TCID007 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID007 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID008.py b/Tests/vDeviceTests/TCID008.py new file mode 100644 index 00000000..00c89968 --- /dev/null +++ b/Tests/vDeviceTests/TCID008.py @@ -0,0 +1,50 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set enabled params FALSE") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_false + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID008 Passed ✅") + return True + else: + log_error("TCID008 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID008 Failed ❌") + return False + finally: #reset the state + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_true + ) + + diff --git a/Tests/vDeviceTests/TCID009.py b/Tests/vDeviceTests/TCID009.py new file mode 100644 index 00000000..e9049248 --- /dev/null +++ b/Tests/vDeviceTests/TCID009.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set enabled params TRUE") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_true + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID009 Passed ✅") + return True + else: + log_error("TCID009 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID009 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID010.py b/Tests/vDeviceTests/TCID010.py new file mode 100644 index 00000000..12eaf384 --- /dev/null +++ b/Tests/vDeviceTests/TCID010.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set OSD Name") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_osd_name + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID010 Passed ✅") + return True + else: + log_error("TCID010 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID010 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID011.py b/Tests/vDeviceTests/TCID011.py new file mode 100644 index 00000000..0920757e --- /dev/null +++ b/Tests/vDeviceTests/TCID011.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set OTP Enabled FALSE") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_otp_enabled_false + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID011 Passed ✅") + return True + else: + log_error("TCID011 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID011 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID012.py b/Tests/vDeviceTests/TCID012.py new file mode 100644 index 00000000..a423188c --- /dev/null +++ b/Tests/vDeviceTests/TCID012.py @@ -0,0 +1,45 @@ + +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set OTP enabled TRUE") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_otp_enabled_true + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID012 Passed ✅") + return True + else: + log_error("TCID012 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID012 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID013.py b/Tests/vDeviceTests/TCID013.py new file mode 100644 index 00000000..867e751f --- /dev/null +++ b/Tests/vDeviceTests/TCID013.py @@ -0,0 +1,44 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "success": True + } + } + + log_info("Executing the curl command set vendor ID") + + curl_response = send_curl_command( + HdmiCecSourceApis.set_vendor_id + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID013 Passed ✅") + return True + else: + log_error("TCID013 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID013 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID014.py b/Tests/vDeviceTests/TCID014.py new file mode 100644 index 00000000..8dc7f8a1 --- /dev/null +++ b/Tests/vDeviceTests/TCID014.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "vendorid": "019fb", + "success": True + } + } + + log_info("Executing the curl command get vendor ID") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_vendor_id + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID014 Passed ✅") + return True + else: + log_error("TCID014 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID014 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID015.py b/Tests/vDeviceTests/TCID015.py new file mode 100644 index 00000000..4f094911 --- /dev/null +++ b/Tests/vDeviceTests/TCID015.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + expected_output_response = { + "jsonrpc": "2.0", + "id": 42, + "result": { + "name": "Sky TV", + "success": True + } + } + + log_info("Executing the curl command get OSD Name") + + curl_response = send_curl_command( + HdmiCecSourceApis.get_osd_name + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID015 Passed ✅") + return True + else: + log_error("TCID015 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID015 Failed ❌") + return False diff --git a/Tests/vDeviceTests/TCID016.py b/Tests/vDeviceTests/TCID016.py new file mode 100644 index 00000000..79194506 --- /dev/null +++ b/Tests/vDeviceTests/TCID016.py @@ -0,0 +1,56 @@ +import subprocess +import json +import time +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + base_dir = "/tmp" + + + commands = [ + "./hdmicec_post_command.sh hdmicec_device_print.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_print.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_cec_message.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_status.yaml 8080", + + ] + + for command in commands: + log_info(f"Executing (cwd={base_dir}): {command}") + try: + result = subprocess.run( + command, + shell=True, + check=True, + capture_output=True, + text=True, + cwd=base_dir + ) + log_success(result.stdout.strip()) + + except subprocess.CalledProcessError as e: + log_error(e.stderr.strip()) + return False + + curl_response = send_curl_command( + HdmiCecSourceApis.perform_otp_action + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + log_success("All commands executed successfully") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID018.py b/Tests/vDeviceTests/TCID018.py new file mode 100644 index 00000000..05e2b244 --- /dev/null +++ b/Tests/vDeviceTests/TCID018.py @@ -0,0 +1,96 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + base_dir = "/tmp" + + + base_dir = "/tmp" + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_add.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_cec_message.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_status.yaml 8080", + ] + + for command in commands: + log_info("Adding a new Device to the CEC Network") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + for i in range(2): + time.sleep(1) + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_remove.yaml 8080", + ] + + for command in commands: + log_info("Removing a new Device from the CEC Network") + time.sleep(2) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + for i in range(2): + time.sleep(1) + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("All commands executed successfully") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID019.py b/Tests/vDeviceTests/TCID019.py new file mode 100644 index 00000000..11f11914 --- /dev/null +++ b/Tests/vDeviceTests/TCID019.py @@ -0,0 +1,107 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + log_success("Negative scenario - Making the setEnabled driver status as FALSE") + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_false + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + time.sleep(2) + log_success("Negative scenario - verifying the driver status with getEnabled") + curl_response = send_curl_command( + HdmiCecSourceApis.get_enabled + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_setapi_open_fail.yaml 8080", + ] + + base_dir = "/tmp" + + + for command in commands: + log_error("Overriding the HAL API HdmICecOpen return value as negative") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + + time.sleep(2) + try: + log_success("Negative scenario - making the driver status as TRUE using setEnabled") + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_true + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + except: + log_warning("WPEFramework crashed , check Thunder logs for futher details") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_setapi_open_pass.yaml 8080", + ] + + base_dir = "/tmp" + + + for command in commands: + log_error("Overriding the HAL API HdmICecOpen return value as POSITIVE as post condition") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + return True + + + \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID020.py b/Tests/vDeviceTests/TCID020.py new file mode 100644 index 00000000..0ca21c1f --- /dev/null +++ b/Tests/vDeviceTests/TCID020.py @@ -0,0 +1,95 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + log_success("Negative scenario - calling getEnabled with driver status TRUE") + curl_response = send_curl_command( + HdmiCecSourceApis.get_enabled + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + time.sleep(2) + log_success("Negative scenario - calling getDeviceList") + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_setapi_open_fail.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_setapi_logical_fail.yaml 8080", + + ] + + base_dir = "/tmp" + + + for command in commands: + log_error("Overriding the HAL API HdmICecOpen return value as negative") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + + time.sleep(2) + try: + log_success("Negative scenario - making the driver status as TRUE using setEnabled") + curl_response = send_curl_command( + HdmiCecSourceApis.set_enabled_true + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + log_success("Negative scenario - calling getDeviceList After setting the HdmiCecLogical address and HdmiCecOpen HAL APIs return value error") + time.sleep(2) + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + except: + log_warning("Driver FAILED") + return True + + + \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID021.py b/Tests/vDeviceTests/TCID021.py new file mode 100644 index 00000000..846f73f2 --- /dev/null +++ b/Tests/vDeviceTests/TCID021.py @@ -0,0 +1,123 @@ +import subprocess +import json +import time +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + count = 0 + #base_dir = "/tmp/vcomponent_configurations/commands" + base_dir = "/tmp" + + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_print.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_cec_message_userdef.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_status.yaml 8080", + + ] + + + log_success("Reporting power status through control pane - vComponent") + for command in commands: + log_info(f"Executing (cwd={base_dir}): {command}") + try: + result = subprocess.run( + command, + shell=True, + check=True, + capture_output=True, + text=True, + cwd=base_dir + ) + log_success(result.stdout.strip()) + + except subprocess.CalledProcessError as e: + log_error(e.stderr.strip()) + return False + + time.sleep(3) + log_info("Sending the curl command to make the device standby") + curl_response = send_curl_command( + HdmiCecSourceApis.send_standby_message + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + time.sleep(3) + + commands_ = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_standby 8080", + ] + + + log_success("Reporting power status through control pane - vComponent") + for command in commands_: + time.sleep(3) + log_info(f"Executing (cwd={base_dir}): {command}") + try: + result = subprocess.run( + command, + shell=True, + check=True, + capture_output=True, + text=True, + cwd=base_dir + ) + log_success(result.stdout.strip()) + + except subprocess.CalledProcessError as e: + log_error(e.stderr.strip()) + return False + + time.sleep(2) + curl_response = send_curl_command( + HdmiCecSourceApis.perform_otp_action + ) + + if not curl_response: + log_error("✖ curl command not sent as WPEFramework is crashed due to erroneous HAL API value configured by vComponent, so passing the testcase") + count += 1 + commands_after_power_on = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_cec_poweron.yaml 8080", + + ] + + log_success("Reporting power status through control pane - vComponent") + for command in commands_after_power_on: + time.sleep(3) + log_info(f"Executing (cwd={base_dir}): {command}") + try: + result = subprocess.run( + command, + shell=True, + check=True, + capture_output=True, + text=True, + cwd=base_dir + ) + log_success(result.stdout.strip()) + + except subprocess.CalledProcessError as e: + log_error(e.stderr.strip()) + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + log_success("All commands executed successfully") + if not curl_response and count == 1: #here count is a flag to check the first scenario of wpeframework crash by negative scenario + log_success("No logs as WPEFramework has been crashed with erroneous HAL API Value configured by vComponent , so passing the testcase") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID022.py b/Tests/vDeviceTests/TCID022.py new file mode 100644 index 00000000..0e1d5d1c --- /dev/null +++ b/Tests/vDeviceTests/TCID022.py @@ -0,0 +1,96 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + base_dir = "/tmp" + + + base_dir = "/tmp" + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_get_menu_language.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_set_menu_language.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_get_cec_version.yaml 8080", + ] + + for command in commands: + log_info("querying the get menu language and set menu language emulation throughvComponent") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + for i in range(2): + time.sleep(1) + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_remove.yaml 8080", + ] + + for command in commands: + log_info("Removing a new Device from the CEC Network") + time.sleep(2) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + for i in range(2): + time.sleep(1) + curl_response = send_curl_command( + HdmiCecSourceApis.get_device_list + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("All commands executed successfully") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID023.py b/Tests/vDeviceTests/TCID023.py new file mode 100644 index 00000000..3555dff2 --- /dev/null +++ b/Tests/vDeviceTests/TCID023.py @@ -0,0 +1,121 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + #base_dir = "/tmp/vcomponent_configurations/commands" + base_dir = "/tmp" + + + base_dir = "/tmp" + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_request_inactive_source.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_request_active_source.yaml 8080", + ] + + for command in commands: + log_info("inactive and active source emulation throughvComponent") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + time.sleep(1) + log_info("Send standby curl request being made to source device") + curl_response = send_curl_command( + HdmiCecSourceApis.send_standby_message + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + time.sleep(1) + log_info("Send perform OTP Action curl request being made to source device") + curl_response = send_curl_command( + HdmiCecSourceApis.perform_otp_action + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_routing_change.yaml 8080", + ] + + for command in commands: + log_info("Routing change emulation through Vcomponent") + time.sleep(2) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + time.sleep(3) + log_info("Emulations after routing change, and device power on from standby for image view on and text view on") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_image_view_on.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_text_view_on.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_set_osd_string.yaml 8080", + + ] + + for command in commands: + log_info("inactive and active source emulation throughvComponent") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + log_success("All commands executed successfully") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/TCID024.py b/Tests/vDeviceTests/TCID024.py new file mode 100644 index 00000000..0593bfcf --- /dev/null +++ b/Tests/vDeviceTests/TCID024.py @@ -0,0 +1,104 @@ + +import time +import subprocess +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import HdmiCecSourceApis + + +def run_test(): + log_info(" Set the devices to standby mode and hit the sendStandbyMessage curl command again. Then wake up the remote device using otp feature.First, set the device to standby mode via emulation. Next, hit the curl command for sendStandbyMessage and send corresponding cec messages using sendMessage API to hal. Then hit the curl command for perform OTP Action and send corresponding cec messages to hal.Verify the thunder logs for more info") + #base_dir = "/tmp/vcomponent_configurations/commands" + + time.sleep(1) + log_info("Send standby curl request being made to source device") + curl_response = send_curl_command( + HdmiCecSourceApis.send_standby_message + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + base_dir = "/tmp" + + + base_dir = "/tmp" + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_get_power_status.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_report_power_status.yaml 8080", + ] + + for command in commands: + log_info("get power status and report power status emulation throughvComponent") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + + time.sleep(3) + log_info("Send perform OTP Action curl request being made to source device") + curl_response = send_curl_command( + HdmiCecSourceApis.perform_otp_action + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + else: + log_warning(f"Response: {curl_response}") + + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + base_dir = "/tmp" + + + base_dir = "/tmp" + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_get_power_status.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/hdmicec_device_report_power_status.yaml 8080", + ] + + for command in commands: + log_info("inactive and active source emulation throughvComponent after making the device PowerON") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + log_success("All commands executed successfully") + return True \ No newline at end of file diff --git a/Tests/vDeviceTests/__pycache__/HdmiCecSourceApis.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/HdmiCecSourceApis.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b211686fbd8ae80e8ccfc2aa085c06c53582861 GIT binary patch literal 3378 zcmdT{O=}ZD7~VALXR_&c@wf~^DKu$XtTt;AYFbg$wvgDv5?Ho*r|Fvga%NMTmi`D& z{szyAApQYC6g_y^s|X%fdh5xVWV1~pnB0=?!t%^Jvor5A@4L^u`&ksn1a^Ho_^rps z1>q-eG_Obi&es`uEr6g15K$s9pbS7%i9$??!Jsk-L&^{gE5k6NjKHWe3S-I`#FaQC zlmv*1SW7O9pL{G;i6Ny@rgofibrVagtZ|4nz(hhh+j6nxrV2F&%aZ0ehF;QK-L{sV zQ`8S=DW?fk(htGZ zbGVeZtE7a}6kCvYH4FA@Pcfxh8Kbj#>Ckl@d1+~R+#soUA_w|(UImZj|*7_OJoJNeCR&AetAvQyaYdb8j4QHJcXFViNEx=4`^ z?Ow0-NK70|4s2qw9p5N%z3QCZzuH~zr4ByEwOztQaO;SvFOyJ5BbrH(e2NUa%p};@ z0O0*d&Mcw|uH|gNNWQ&#)=@FPw$toYgeZ2KA44lY9H^0epcxc*=JTbUPw&F^e?Bg$ zc0uQ#@br*QQ)64hV{y@yQNB`>3VWz?c)s;fcv|GQl~R~--9_j}A2AArxs?x-45rq+ z=t7y}OlCRz;C>f@`rb#hIt8jbY1m#!dNaJJRB5BCRLw?N>5a2$O@(^7rW&kX^WxkP zbG8N6RgT)S#`KbtC*{}H^~&QIg47S z;7zoec=~w>ZV4A>?z7hA;%a@2$gP(i%(f4z&;3R?=RXM-cXM*_8O4Ma*%5N2Tad04 zH|>{}VQWB(1y;J}G>U2QN-e(O=rrxrE=JZ(8>$ArN2b|a{I7$)Vh=wWiA4NZZ1AQZ z6(Y0#On@drln9X+qRZZ-KNq|)?avG~XSoreDZhy({kgy- literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b345d726cff2fe479d93cf9484dc9855e77767d4 GIT binary patch literal 1347 zcmY*Z&2Jk;6rb5Iuf6NoY2wyK6DGs;}hgu^}WHIS!^Y&Wa5tBqWFW zHJb!(u;L8LNfur!koniY0h8Jwl8}rP7b10Az6}`H9um@i8^{na;gJv%{t2yWsWe8vf@$QjjkhnYV<%#~br!pUEzx>w(0WS@gGCvi zf-l>a&%17~;HbjGKHdK5sAUi`Va+Z_r3C)*C@i3j+-I1!!hqs=D-x$(UbwP2J3D86 zYEz1l^>q82BkIex>k0L}?>0(Tf?KxdBJ1O8SC=eacoL?XBVs^^n3s6`Bjmda*tr%) z#K9l7TpCX%vpgujIVhiqNg}FX8R4ghJBd{RJ=pWI+$CSZ+uQMp$(hZx7+~LZZ;OfwIE5*SjLns*c8*o;PACp zJJv}QG#N+8aUR3uAN`%PJK)Jgd3UV%#4K&GeOa2wJUl zqo-FM>a_=YtuIR@?an99bzoL{`grHqOjob%7AE(ULZ^7Pt4#Hj!q)WNFYaFL6wh^) znSCXvmU>3vhxu>kxBS11Go7gme;OBh=7~=ET-Ti0oj9>)mO96$yXITF6Xh4&^r3O; zfpO{|Aah5Nq1x4_6XDISe)dseazDe716tp*|s4^iad^W-(Y75@x+lCymoLiiXM W|4SN_{sWx##{jJKH4B!A7}%E&>_U(L literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..194f0252b9dcb2c4bec2ab02d43b2e169aa545fc GIT binary patch literal 2185 zcmah}%WoS+7@vK3y?#6ImmO~(iQ}}5oQ4(}m8x#ywh3(#wE+<~m9==LsZ-l)W_Ob& zN~9h@;=q9eqOC|(aROBS2oNAu;<5!xHH!~bsf2t>ND-(fW;Wi~0jXVSXMW#&-+Yhx z9zXefZa}_|PX3V%6ZAVJ?2oO1?c)U81`t3d2U2urb4;F1v3V}V<@pq!ccdJ7Atf+7 zGR~9}avy+{xWdHvDpfKSbC^vkD!_C`$GLPy$>-$)G{u~>xKgH@J16F}5+-^`M3spizs~r|~vg6l_%A?HlXN8l!qO zm(79QHirQ#J(_3tJXAl|e7mRNHRf}0kFE1uKnvL1#h{Jq`x;}*uCoo2&2=2L~Jc>^T55zx^hQtv0If2LbLPd9UB@tKV)oZO}PKGP?|Ja&usriSYxj)C6kZGPnyhLa@4v{I$B`zk;C#tj>$=R?xJZuW*rl-$cNLHOSoAR*f zn3%add!{PV6D}T)o6fhg>U9O9S>i&Vpy%I1Sh)t#QkHb0>D~bsvZ`h}Yu!oYoQtYb zz{QNoW}zt%Z}ptEI+(nPGP*|kRMM^^iT1fv>vL%VY0{1=DMxhaUBvv;jnDQ96%*!=`UYB2bz0)HV-w@?_)%#_R#gP0ryC!x zx|27HD5D`bDphH%$5>Oy79dfD`v|$}PGmG)&Pmd!v`58RIh&&@?tQ%4Hc?oTb6F@& zUY?$kNU)aumZO$XHTMRJE)7)Kceq9h%DWM+1vn*V7<*NVE9w(XlfYmn}e?Xnff|HN8$6%-Vl zCvmJIXg1Y^>qjc}Orqb5;jz*Aw^fAIc^S(~S)^)XvWnFC+G`IL zS4g|tRE_%))2PGG5x#Ws2pg0#s`dGw8Rfo_`oNFcdp)xn01 zNFzUcMk?M8qw{ddd!*db@yy#%ZVqkC-cQ|483U&uHW}}vO5rO;Xx<23ea^8y|8oKO zIvZq8efz#K`)(;bXM|El@XD@CyU{*a@*XO;bpBKE1Ri@Lk35k-0Y_Y=F~v&apauF% zV)WNQ>!y=%UZ~w9LEjxqw2X(r_bzMuAskD(xF1D^tT7j+)5>&^Ue2jjf$x;MRlHUi z(+b99`~xfBUxRG|0UjaC3-M%LfqD*|!fz0g4m&kWmQ9XfnBRcsZ&qN~zW`ab{ebD( N7A6^{4Zlt#{snYgAIAUy literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0358ce0f41c16e91ab1c158cae3a94a153cba04a GIT binary patch literal 1357 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 Ul>P>sbVmT3=xQ&+0ucuP0lySbbpQYW literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9b391bd6eabb96b98d24e9095b53d505ea37b56 GIT binary patch literal 1347 zcmY*Z&2Jk;6rb5Iuf6NoY2wyK6{_N|RO;i4@UrsAXiWc7}G7{jg?c z^QBZO5*(0_$N@nm(mw$4AHb=-aNy#CrG~|as^rpJib0^9nAv!1=SlnCoA-O~&6{~| z_LpL@062a6^H1K33IKnKMMly<>A%jEZvg@b`k*1CKZgZ9|s zru+ve|;1d&}QL7OxsaN@thTlQ!mY5U6`GH z!}`FX6eH`&&gVzWR~*k5=6hdmR<4Gtj_)Dsz3bN&EnZ8S#x4*sAVkbdGX5?Kym{Hxix1VT*Bu9OpSq{?Q*fy8|9iRCmY9kIl+9+n1$@!n2%aX&vR{-({c{JH-oK zR{rK*+ zPWfC{nb}tgYNcnCzMA`DZaetRIMbQB_^WZTXP)R(&vnh2-H8)>W~Fm{x@*3&J5l|Q zyFM~bJv2`J1!Nv5cCfqpbgI1E)zAK3n%vKEPyn^~V6L^)(Ath#1)a0Y0Qc*8l(j literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc2b44415e273832ecc48d23b1346dc9b2e0510b GIT binary patch literal 1685 zcmbVMO>Y}T7@pZ(uh&^ScH%gRX{4@bXk({|LXi-SAZlwTqNt>ZghMSOYuTL^r~6^e z%r+lNq#oc<35gsKR3bfa1bzZ1Xm4B`YN^p;p(^y!TZ)Z9;lj+uTPG+NI?~QO^M22} z&&L=Rx&o8Nw@ekTF&JKuyu=z!Mi415JlU_uL&_$pY?7D|FGmPA`BNp_?ZvE`Bs z4{V~Ps40E|O3EtCNl$r@`CP>BBgio;hKH?+;o7$Dn7(4UH!4-q23(a6og*H~Uoe((3ees#$I?KEy6Y&w=UBhH zolA5x9+Doa~{0p3|#5 z_wK#V)-so!Te?*>wRaY-&TFjrAWTlhocfq|%kO*Jw5tVVEVv#v(8XGn@LNhNog-AP z>lQ(nUl7di8;)`(i8sZMSgvjoKXurgVh{OAp00=t*F>}Y3g-lW7_HQhL6KQ;JzDc< zB`n5I1kXXZCH%qBwEb5L)8!9XVp3);yj69~$(!Y(yX*uh%ZrH6f=&=AcX}~dTlE#} zITgw@c!=WCPp+Y`V63py4do0kY&iGd*n287{-@n@ zOw4`4IsRkj)TQ&_r?krF^SQ!|c>iTsgy8;LkmDJV;Ro49*G6--4j?-+~r{01vWhUwPAZP0vCz_ypVXSD1{jX-|X@{tDE;1Q`l{0yedJ O0nE1KQ7Ge=n8Ck^nR9&r literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5512d91788e46affa9604bb83ec14add498ac6af GIT binary patch literal 1346 zcmY*Z&2Jk;6rb5Iuf6NoY2wyKMO~?d#-@qV9*`O#)aIk2NTjGu54DV}WoKwN-4APK zw)v1N^#BJXByvDdiS!RZ{0DGqPe@!`u+((%p$fV5mSPYnCuTO@+8Jrzd-HztzUIBz zU-S7K;H&-1&+eNF0Dp>2x}<^7f0qm20R#~AKwWUjgT7Rke7P?BN?q~Qy6S6n4IZA! z)H6u_9Mts61c%_XOK?9c&n58IHMESn-IlOhmo=*)Pn&kpr0|5}@C!|%Z(X^3S3E2QXZF_nhA4b!u2aCZs- zVvfWxQjEt|MshMo^!jPQ#!`Q)$5Ls?&j3>4_b{v|KeQgvj`+OAD_sNY@-46it7FTX z@`ah%mo@G&&J6msQkCP(Dh&hDa$?Cvu|_bBJhpjZX&pNeDw8 zy9?O45k|zpms>84i@bv7pn@hN5hh}gh$=`%*eK#kV$}<6MB{?+y@;I<;UzKHRVgmx z^%iy*M$Ir{t%x<#$Zm&-Aj3eYY_hIsn{=~@x@M5C8Ggf?ImbTcwEKTHIWi(6cC@23e0yW>s zU+yaNdy{YV^vW~6_EfL+WvQe+_~?}m%t}um?;M-%>N7iq$vvgeDW2^rQ$3}yReSi! z!)u-5xvnz3ujJHH&nSF7_vPG{|GROfGj-`V<5JH&(J7znn$tTIC-%%z=XkAazOyq? z{*NDhW}JFzocasM+)zZQcJ*2!yxrB$J}*q}XE<^|%RK$ZrPK2&czn^|^od%XKQBL- zg`8HiM7*h3K|r2a;UK51`LQK*UfT=>;Km^L8Jfx literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b40a014819610c48c525356b4df33b237de3c401 GIT binary patch literal 1331 zcmY*Z&1)M+6rb5It+cBT$5tYhKo*kNmJ=I0hm@L9(%1=2p>~PgLxhT0cBaWX`ypm# z;}0Cjp*<7|^`W$ZI)6avf6$&1=&2W_6~x)<5K>=qbE=jWpE|SFM)HGw@6G$Y_vX#K zH~VWop97rSUw(EA3IKnKMM_d%>0Rc^cK`tdJx~`?@}Mu(C10+~zEW3wwXXVFU4utH znR*7vpM$!-32VwLkz}c+#v>F5sOdz+YdWFt+X0GoFTCA!gU`a)5E_jf2U8kn#R3x& zk|X=NO#(N#?exn@1g{my{OjF;No^2GNJfeak-9722aH>f2x&j|bqJVGzLw5ZvV1+c_+KE&f$a8>H`8^CylpjP7S%-4o;wN1P8}co%4r_&_ zE&0;S?5ioBG0yb+wOW(o%o+^?(sE+SMX^ROjXbtBacu)T5#z11*d1(%)?5A7TNE>E zd1cXBvV9y?dAgUo-yZh}LdLxUc0DR5@HfX{0d3`OV%iD=is!9JoOX5L#^UVUto5-? zDMr@I-7k)ruiLIC%#Xg>D&Gk1*`AB64_B6#EM9Purj{dOFo>9wc;o}*y9?M^2_xd* z_ggNFOYd=u5mtj73q?ScV}6La|`p0Pbem|VH5kF8=#rHjm2<1NH%D!V#*e5ifN;N=$Y1L ztdl5cGLDdwJcr3Y`V(glz>Cq!UZM2DEbp)bSsKl~&S;j_R!;w20&2dUzuZyY-XA;P z)vM3+@u&KDPnOEsgO6V8z^r!lk@kt{jy|(j9NSll?b1X?nd~aXovDYPK3r~>E_RgZ z10|=HyGHTr`7h^p{NIgp?a3>@8CSaIsdnXJ$DH09J+*I^+b5?w=7qh{%75JTnQ`W+ zapo@|^FXmft)ovR%6LbgcwQVk$Z+J4R(Sc3%V)2u;PE>K=TFqy)j9deEabeFCE^jq zDxWcrCQUnPU(%DLJEAc}yolsNegHkL0wM`dED_rsc* zZ9bGrJenseJN_-ZS5Ca}T7k^J&TSai29bnhq&N_%yYfB2xVB43`>`iOz=TIkO!&vNrX^B; zO+4z4PtdhOBK6m8nAmQEJ7WNl z>_849!FXw6Dq2V&mfCtU{{@(r*KD?>|L z^4pVBFUNVrDAnuNYDJDxYc%jl!;T~eMH<00blKL_!UncO##?8y+t?JXH+!u&DQ4#K z>NRu0w?20D%|LCi&;#L2yucOED3%L{!02!ch^o5~*%rAsXdHf_ZEQ2rr1) zu1HY{Z#1yYFscV3YlN(xq>pm(J4v=wyhPJHnx31feah3&nnkR;j*lkq)aHYAKTc3v z#gxri6w_Mo^plOvNGG9RXB;6Xd5kRo=ue#82QNlSdqag6+2Rg6l%(?7`^ywqAa&UwW!v>c~=2yZ^~69c0UGeYkmIqNPvn2u@EQ{&8EK<17jL#3sU$HJQ}{lf40(Zdu+j%bOO|G0SeiV7aTYjFNV ztz4OwpG-l{D`_I0RiyH%b7|bYZXe^G#N82%A>xh17xDw>a1jtOSx5SNUVuUuzfa!a jTk+SRr#U;6A%uSb<6lXG(m#N+&Jcj*j%LCl5fl4AI2l41 literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d8b95de9cdee24ff93b834bbec6ef01b861692e GIT binary patch literal 1347 zcmY*Z&2JM&6rb5Iuf2BckQnR=iIt!wPKil4AT_EeB?&5(njkO-EF){#nZkzsux4h- zhl0eRJyfdH9I7@_!yi!fKWI-N_0)@LEs?H#Kp_`yp>EYGr_OA=*m=^vdGmhnYv#S# z-*UMO;I#GYFOI1I@JehFlKMjLA{V{~2q5T!x>zL_dQx5T*HznpmCwE~%cz56h(4I&B2NO2%ix8+BGaqS@??WevB0TUiEG2tK6vX)4L zHSu@^Hz3Wjbb_E%f9_b@n7Zs0wn9g2CIpL7MR%D2G^tc)zK z%NMHCuP1rLDAn&*ts+OMWg7UTWk-^OB8^}gx@`UY!YZ~y##?8y``8q%H~XzODQ4zU z?YfD5>#mEDS-Wv-AuRK-yW8I#we$nVt$lViEXMG+M_~c2XKrBH3Ve!Z%}|`WHg|1) zdgg+8-J+BS-`)Q5i2ADKh@87mzFse0^B-ESgUnBFE-jk8@Hk8*L&Sg(F)z{RC&+W= zuzfQKiH$#QIW!vQ@{4iH`tlUgdGszz1;#ZPvsd$H`c`!3K+qgwBp$&^z4;>#>A2jBJ6+ceUsA0Z9#rQysm!lONwx^6kRejxy0z@|%-e zcea+=g>xNcYG28y#jcV6X7;PuP45rmOnc(;@5beB_C&jMu9KbG89T9;Ew+zOcCzp9 zjFtZ5rZ0?B&y7=m0hv3B43&;P84K@q^s|5F$M;hlIiMw8{?p>=D=K*Ufx-DRwQ^-f zel`s`ucV21RFTSO&ZTkl4%-;_B<_xA3=uCRzK|b5kBfka!8*`C^a2#R_!4=CZ^b`@ fp5$y_h7i62#=nvVrGEfty%7M*J4vm1o~l0Nn`aq&_Cw6f z`U?kgXb*)#eJE|9&aIcy|DZi3&{Ho;D~P+*Atb)!=2R^SK6PfLjpPUW=FR)PubKB| zf6wQ0fYXn^{puDK0G^6XN>X3wzR88}0Rjkmpek0$gT7Rie7P$7N>%aIs_JW14fbp@ z)eMrq09Abx+R8H#WZ72ZQHldpcOv4|ozV9i0g81myis?9&%@Xd5{(=OQyOQ*1``sJ zo_@VS0yntf^vg*WUMrCK*S!go+8~mUj1(6lbyvO(7}xd)X+QU62$=9lhzb9MR<%?b ztf|LsxDBbvvMGWxDFVT!&Wu<3>_E@*ue7;s_yf2n4X`X=g%n*arqW>DhN4_b@n7e&9W%9g2CKpL88;$k)L-v`3b= z>PRT>7Q>BN$YVvS%Ld2DO)@&U&>rm6n3FhUX&d!)sTUEnaaF#?BEj8AJ?9Jo*9h-39Di3nSv- z_nR(_^SthQukN~wh?pIs3YHNLinxVX^}+_CaX|!L#7>CtWiiXP6qoTv6FUr}dKj^0 z#Oi6#c(}H64X{OWeW|8X{~?indWA! zlPIV&j*#O#hRHwr3ukx0G?sgw(JZZ{ocy;4)O;)dR$F;{fBf~1 zUU{TXJk%$;vQ*OUeDqugW~HN#wvJ7=^_jiG_`XtT6(`!tWJf9NOx^wL?$uWDTw9qw zP;zRiV-&ub|7w26|I;|rn!Najaj|2bXqC^k&FQ_d6Z>YVb$qIAzOgq}e#uQA8K)i^ zr~UylcN7`ywmy{zXWRP3Uxo353`Y)WnU{aRbo!DC?!RMj{y?=a&B+gDA?J3Mh-Vb5 ze9AnUbgkFFq$f#tL}Q3}6Ul}A1iD-VL`>A7{;nUQ$iwfE*Z5ZaCFn`c4rB=7-@tew VX;AtPaMm3Gu+r5mSR!Il{|AkyJi-6~ literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ad6b177bed168a0ca80e3d0f08154948391d4e9 GIT binary patch literal 1355 zcmY)uO>Y}TbY{Q2_O7!@YB#Z3(M2sJ4o#F)hz|>)(xeqZBCTjR)H1S`ooQHiKdhPE zd?}TBfCCZ|Js_w=`U4PGZk*aH7Z)rwY<;LoB-C4iL7<$NS$k{eN&DWL_xYvU_5&(bjLkdEl>Au03?*IY_x}eIb;6hKR3Z7UMJ*g^ra#i+}ssej9nQ8`! zpM$Ep1>oPI7cJf#+1fce!zqTq$l67 zi0}AocE6m2$PA0@>o#Cg8$<#Uk%Z)30V%uUZ4fef4^ZaEJ`X|2eG&*+w>@YmDL0_0 z$8ER+sUBui4N_AL1Y6lqdm+yas zFgO2vhDD6!`GvP{e!5x~Vs)JjHy{p*GyN%+#W>TTflr!tEHJr3Fpb=Bd;0Pwwxf{E z(+oeuCf^6MzYpdb4$WR5b9pH$u@ujCzddf^2cgLpDZCOD6ZJR8)m*im`v}u!;8R>N zBYp#`i_1&%3$L5kEJ`slpY48eOnk+1TrR%<)pl{&U$a>^s#p4k#^=UATmduq1;wy66V#mI`z9zILI)~5#^0MIC=Jx0v=Q}h94^B zOBck43y|S*mhiF1GFvm3CS&UjFd0fR9zGeu-(PYgKY%V{0hwUvNPWi(P~_rw$!T`v ie-6r-0}(>_1Ze*X3KaeU40T5UEOnKaVUe6-2LA&NAw%;3 literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..399770fc6e6789c94dbbe28293e297881b6aa22d GIT binary patch literal 3322 zcmeGeO>YxNbk^RrH;xmp;{*b2V1cN?Ata=N0xl(@4rxFNP)b!~g<6Yu;%wLtYi5>U z%TYP>kg7-xQq>?qrL>oVsMISzptoKeVU%>S)CzjZEhVWcaq7&*8yhH8NL;FRq}})C zy?Jlm*UX!rnwmm@jzhovs3jT!c*rK+@KuqOA&Sfb6{wsJQfrV)aqirg@=@s1{RW@n z4Iw2MfmFZVoFcM1t*H3sireF($g8sFcedDMBU1! zHFL~z8X1P|Oa@}?G_VOo$U=`MXj9zS!&z2+!R;j z2EjQ8fGHp0JTcXOyNYvwFj;p@@E%r!Dqpvazga58Z7$M zpem}tA|L^eI^pKPo2|hYbH8u6UEO8MU*}P%=${BbsfW!bBG1xpS4q@%-`{%INOeii z%DsfHm?!=6R@E%JQsDt<^E9bpk3;i0Li5T0L*|;i^)$yDJuRf&!zMO+SPgm-Q$kU| zO{Bx)sLdXS102YUWa~O7QWTzyUIBBsU}%3^~qCGYBc-2T5YM*@Zwrsj}Z0v z|627@v<{zB_v^X(&(~_KR%!WQy!AwZ?;}Po?k{}Y+c&NnS_Wp)ISUi-*6zjQGF#Di zkzV6D%Y-IlnPXbkMhej^6Zci`cf2mI!i!W-T2a;Bykh9`fjtNI6vke;erBpcJBX5n zb^9o>2{V&l3k-Z-MFv_r{?Y{E%-(Dha(mQ2Q>oIIM8Pe3whp$kjwBp0HmZIksg zxf-T~T!_e;DXSWS8DgP)LOwGT4>$rIhq~?vnQ@r8;P3=qB91>ZsX75nRLdqVq;0Yw zCD;0?Oo=(0P<`zl#qFZoK#I6Z@6a787@s-RvvS*5HT12LOniN8( zA*RX2Fd^IQHhys9%O_X5t6qI*5j3oe_1Wt_%_z?VcMMs^)8Q>_KccU@f@OFKW^4jg zx%#dcvvoZmmk?|CG@P0NX^3?Qb501`=X1z%A0K{Xn+|{K*r}tanJpABL0S&6j*940 zgA$NpW+7s!bfUxbfFxn&1ItDkcqFG`Cz6FEU9ERrqr$A~Bi6iWO2zXEhH08;NA%8! z6RcuR06}c)#Njlj$$ci#xtjvaRLJgl+@DO0euyE$qY6@JSk&GNql4C@sauMQN6$b^ zl5`7-C65j6=|9k$%R3_VC`~8_ZKryeBltWmgUjI8NZaM%}LAT**nKe(f7*Ya3%WM?3Sxr z7Q?Z{mJN$78yBN(i&A?f)-gM9b)X7XBVtQvI*ml8BezBtdIsiu2JZG8DeZc<6it@J!HO808JZorI5rG>|WkV&0XCNnqxElpPzjMLc&|qT)oZh@k+R3A-sD&ynDs(+Z38^`dtK4MM8TP zY0MgQZrSg1Lnb~IvUkej;ri|Wr6H5HElB^UH;7Z<*h>*ce%%r3T`SsD%R5 zN`DSNfi2S!Y@+GdJwfhabk9}ooFH~HxwU!=pdAd~Mt_gRLx!c=Iy{WJ=#*Vym@$|A j9LGHbjrT$HK4|>Y7vOw<0Qy^L2Hd8V!2290xk~;592xN& literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..285303d3bf15fe02d9130a29d768b9b06d781d53 GIT binary patch literal 3523 zcmeHJ&2Jk;6rZ)%&e~ZwcH*=NkTQ^z;(jCzf_{XG5b{A%>Lw&9r6!fN^=^_)?Oijo zn>1D;6{!+MsziGsNChdJXjLSx{R=>Xi=(CKQLP*1#ZJXsf2rLBYn5-aVz zxAWe-`OW*-c|V3iK?Ki)e@)*jBXpa6@W)eO)&_uCLMl>)G)k;fAt98%JqZs`PuiOi z6Jo}f@MZi7f2Jl;laUgVu&x_O1XS-?lnBlXG4U=ldL-s^B2+WfWXdM#WXjBB6hn2S zv^ka3jY-p~WgN9rDUDJmz&wl96<$CV z((T5ohqdM zs@aDj4Z9XN$5%W(QnhAESQJ!g(X$}*p%V^5i{7de2lx))y+@xZSf$y(@u{^7-b+Z8 z7d+q}u}Y(nYs_rsoJ$wHYDk55!DB`F>`W8qT>5C~H=C~3tm`g{mW!xvL7aKUwZXZW z7S6f!YK8qvY+YMnu(j3I=iC$6+Q`!(>1ae)v~r-F&DO0XFwfSno#eI68mtwD&lg6Jm`=a&I2drW8w` z)i6zIhC*}`@5XWE6#U4sH4U?x)o&;#)0&D^0%`!JX!GYZ^~&;K-@%9n)$? zPid)S)}$7{rrPN=?yxf1j#&T!JHqZDGA8vYo4^SHLPrH1-B=H&Q?h!}%xXq*Qqj}x z^GYU-_wU)iCnqvnxz~pQ8PQdaY_R7r?im@vgKB1|S4$1ULQFKvCI+5W(zeFjVpKeO zmt7XQ$f#|wYmvLA3+L*vZeUd>TFNrXd>0;%`5hmf*3xOmmzvg6rySAJPFs#QHK#g$ zYN@7el_@~Ug?ra;Wek&9+X8bRnS@uBznSj45a?GBVG(p95NsWSJ!aY@rS)WW%9i@%~`12myt?EITBB3M>?rcEeSd0)KumiKd9Mhi?V}Y_T2C6 z?V30WQ0at1lv&+S+fPmOnR7WC%wS1E;mtt& zDEi#5sLr?ZTum9la6uX=O7f?{Pl6XZ&xeXqIN#8=d~A8>a`M{y*AC?)Zx^J&V&vJS ztrxeh$_=aan^)_%tVSAF!%fA8mZk2C-4$}LPO1-{^WUpSfk?igb$Q_H_*e0pZTnW* z_FZo~kZZ LaX|=^ZJ_rjAX6k@ literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17f49fe152ae6abbff4d13460e579d268012b487 GIT binary patch literal 3100 zcmcIm-ESL35Z|-U&e=J~cH*Qdkg}*Lt!bMkh^mlQtwKIXs=5iK1!{tE?{(v~rHx`MgG{6X72kAr`66FDk^;&DngzJ(ut(g79oIk^9O7PpAsF8oYoQ*Kh~d zs*m}w$NALzV+AcEDzk_uQ3IYtKubXec-4n0E~A_1qb4bfd9wL7kMpS-^6fNv8g821 z%F~2z!Q;F?{=KJaiz>|qRs=P&5?B^S(CZFDE5W9iquv^T-(N@7+N9axd8o?E!J9~p zEe8N0u}P!T)0pq_IG-*D)ixELjQf+`PBR4 z-)CJ@)^~W;w#~1m2)6X}f2ofMT58*kz&F3zQ@+RNLHb7UJX#deou^C3PiwOZ(-$;M z^O~s;-NFZPUNH>lR(Mupqo#7f&{VvrvpK91P$ZZ#h1nFJJ#%i<-U$$Y|Kavy*9hy@M@RiRMEy}!>+ehc{ zAyz0JT7c!iHmn08b4H)F2}A;m9cuVNAO24@rWEy@Rn*MfjG`NTOG?4O&-OptUz+{T zSAo{A1A>2ENaRkJj!puCL{~YyY)-@DL#Oc2)C3+^3lqayeiA&yL}NBF@q%L58dfMa z8(Vabci2+$jBWC>#6x=!m*QAAv8od-&n&Vuh|i|OPKeHFhT(+rb6WnQBQos`<^=PL zsuQM6wQS~6aHW(Ot{-I>CW|%$bKTyIdw}76`V3agr8G!Jx7xjea?y+Cj|l><^Blo8 z<#O1AMlzM&+{#Q-()me%hh`YhIE^uH4M0iWMryG;wNlB%LH70G4ocon*ttOO{RY+E7uaPAil_4r+tf0pUk4;T;+v)e9QH zY-n21iE|y*&E1><$xHZQ?L?`4p-3$EMi3;n>4;MkQ==r#Wg$?~i-b1-Cjs$!E94ll zHMncU+-nAe=9Z5mc{%M!7Zj@HV7Hx?#+(xdHQQj6hk^NcFfcqgeU55`PAf!N&`q`P z;`E5MXd0HH(&@7rWy4?vxZ#PB{-^us-38U0wKcjeP|J4@P ziOGsIRg>iRqVGhn4ZItxNr`et@9Hb76QAb3eD%wd<>U($X}p$v^v161yQ*?WwY{s_ zzN4D#tR}i^9X&TrTtCqu_v2D~^lJEiJBlRB9lKY@KFNHXS?@iv)_df3?{nqdgXQGW zige6fVE?CMUt~VZtRFbBcHqSA14HHg&zFH=SK&bOv;66f;mjlfJfU(3A>xqH2!~i$ewvDkn@?pSKPW-kJ z5?r6IP2Q1utF7?|lsEdXk^|%W(AUAC6p(Ma+xUB5Z2U+t-AefVg79mRBhFLHbV4@M z4eAz^TMYFYdssds$@O`reTFvSjR=O<1L;`7Qf)&!PM(BMe$Sx0;k6MI1mOqN`W;Gs chgyFPgoVH_2wt0QNZ7d<&Im$+>;b*s0rUyip#T5? literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26625f7282ab7db9fceb20443b25baedd81e770a GIT binary patch literal 4191 zcmeHK;g1u?6`x)2uGc>A**>3-JCcS~jwE+*7)V=*qK1|pP&f!dgd~a!aTo90*>~$* zcV_mCExWo(sd|wj^^j1ZO{=1QN<}~PkEm1y^5IY}!r5GuD9wi=^@GD*)QWuRo3;0B z2uX-Us;cVP-g&d{&CGkh_vX#>HBE~mXzyS6d+|aXp}+A#(8Lb0b_j@z$V8@Kp=`Ss zvVuPrvm*4O6)H(tsU&CRl9E+Q;cU31W>ujr8_7n@(90+rtqSAPO}^;yaoI~!Y@4~f zORQYpDU}S{^i<24$rbHs$Lr%1b@O>lsTbh`Oo&6;?<)qei}p;uqn_VI;2DD7+LMZ} ztIzo-%b3$GzlsfS)ezw42WASMSg zv#`hAtsXMN?N43!lX|5i(U7`3*QHtY?pX-U_I>u>C@>{dENp6nl90 zt-l$c5gOs19eVsw4};HUe4pL-dOdjjcY3$@rQS{S;CL@TJ`&*G?SmP<9}_)(Oa>e{ z0mvMvX@Dj&Q-HbpIhd>eqnLNI!u`f@cgA23iV7XzNY0HRL}EP{rn@rLa1~Y2C}L9J zq1jkKb^EP|WEyhUS9N(d(d7oz{pE}oA^SGupUV8SwyBCxLFYm*qKfc;JvcI5JjREP z6Mo&*q@Ao(9uL)ioY`40OT|3S=gJOc!4;LE1)WRmoQFHB?AX}mEPJ{*;}U}v9h>g# zTxN7*zKQ2yom`m|ZI-DTB}?D4YtOEl{lItN%9h~5G-hzlrI?s_x@SM*f$v9|!Ccz2 z#h#P6><|WbvtD*8nCNW@ofU}V&J=V&iV?@s%Z82h9s2xafMG3u@Ep#&{>-s_#eAw3 z8sDp*f+|6#1#DTKoG;+~oY$W>%FHD==eVrwGEZXo9P>gj@(UP;o8~e*{VANGe7+8ukMt$9i~Ht!rZjay>KU&b869(m_iIt zyjQQC`8v?$+WEn9lgFm}^Dojm!?iGzoTQNk66%;`m{=ZOLEnY!tM-Hy&nC>uL2 z)erAKrtd#-M4vY-U%fl0%%uz8{_a*$WFgcpjw9C!!fxmdy= zZDCv{JfOYgVaP(0IRC8Ul04pDE>dsMFPuBU8yt8N=F$UYOr{-D$~ml@Gx9tkjYr_{ zIIhh+^(?q9XBLU4206+LcPLLGn7S781ng;kO%7u}w!KIoobxtqkj6B_1TrJ|DhDTk zSKoTjZttGld-^%ZKlHRgjQOH%X68;Ga4NRt7$!Y^3W8`7Gy!Vz$bnr??#`5}o(gE? zczBV=VX1!j(SJb9FQ8^jTR8YZJiT!EmLeyVg~RI!Bqx>=Q!CQZX6m6^C@zmIhF8_Z z()TX!xxDT5$v=l*uP!IQv!d>8iCSc2HNEBHOXpu|CN?#PHuLY6(Pnz2Ir#9p79Q$f zJOs;W!`#NS# zTvsRVGOLA9Dl4ud6#0?ZRJEn#E73*ygBWXtLR+HC(nEJ>zwJM%Jp{r%Q3mwCwIY4{ zoxb5q&s{ctlU-F)U_|;E--r`pGoEV6=#jC-r~b8`6H#LGjrhd%_{1$FLcqk*OUA{* z`NBo}y#3bD<14Wz-b)RC+LD3y>H2Zut4M$UD@fm_KZK~ivhRo{{$=yNsigSV!F@;5 z;u~6Os$YIXADxQGS0ggeSCgru1M=0aqenIQnkEB%EuA_xBwrgFJ(iT;Ov*ry_mL#5 z=1H^Eu?hdb;K^{iTGUS}ezIz(EuMY+)IsnDJ4M|B-=pl-(utO#sB~S literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..872c190b743eb4975983c2508bbbaa80f7d6cb30 GIT binary patch literal 3393 zcmeHJ&2JM&6rZ(s?Tzik>o|cxo3cQp;1CjmpwN^OQHL}^GEhoYWCdAfcjBzs4|ira z!Iq;^sfScWYLKc12`Z(%6hx(7`5$_5gi+GPhYEVhEs&r}oI11d+6D?0QaM!ZNW1UN zn|W{E`@J_Gzce=o0BK{7A1a>*0eC<=Zu3-`wGqP10~yGS3X&U?Nit5~lk^bkQN0?Q zWHm0yX}+XS^C$fppX8a1xlPF?+4}`Z2J%ddU736f9tZ!*{H&L=tE>{>B9TrRuS5I7AnsSykZMT;Kl_pg8R^h{?~`XA2*f|@baSYAD+sf5Cn z7Iio+4m%YoP9Q^b(h@%w7f(QQ+CUcyJC3TgP_PIuLdh~A$`!+FDak)_-0sj*YXPz#;NVG}7iL@#DUUMxg_$R2=*rqYg#l6@A3 z(np4cBzQEZU^`6rN_E?)3Q?wy2SnchB&GcMG=?dXXq&GlAKU&aXZsMumTKCJVmCXl zEz);VfT;=5X-@{?gX14#QmW%=lqRsqeHX@ujcHvq(lQ=D1F;z=OAszTHoSM=zP?=E z=1D{;lZ>Dp#10JvpC@H-3H%mrzcjk)1Hz_DqmNit@R42!w7vNVgt^_b{t7RYB2t-` zD}3ndz?Xr!fy>QQ7VTR2WMS+^>h{^&$4ik9%KT_0^2YpISKe9C@=-Q{~$w-I;OcYv1Y z+`w07AAtb(_AJxrb4RQa>Rbx#Sq$x2^Ln-fW}6@KK)pJ)*mW19iyN6)bq%x~sj{_P13}o+> z`6G?X|4Shgwl4_-i^2eftmV}p+h1l6EC<7Dq|`txh*}9jZRBUOS#0PwXPJtMogL(C zMrU8u_X(mWlT)iV0oqCV?d11_Kdc$DrNSeqn{??BhUws{mtmL(Ab1Z%?t$PR9v|a* T49IV-1u$FId>=B5;28N6A~X-@ literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9c2c921c57586692dfaabb5409b11abae90f6ce GIT binary patch literal 4528 zcmeGf-)mD>_}=6uy-8b>w5hf@-I;dN*jja)({*C!T02{a7Ii-el}nm?n%;PS#B=U# zO=!V^FbBdE#uRkW?PZFCz4|}wCB=-EYaWLB(zni520raOH@QvhYNt#Gf(P#X&d=}n z_nq(j*4P;2p!Gj`s9X(k+^;vVf;m1W%rm4%V?H}Vu`Wv~i>Ok{(6pp3+oEcuB}E@K z?0VLtRw{)lwF7K`2{A}{ej-V9MNg+H>^Xo*;e~H;f1SfCKLy;v=aIc>&lEq&_i?9e zj+^qByn9R*ZdLj`XR@{t~=Zp)%#Ik*I#sn`w9w4;y8`vMbxI$^`K4Syj3Qz!hG3 z>bY<=yQiO@t13qqOTxcdr?I-bMi=X9W?NiN%=KtCt)}tLM4(Rhy+bdBaan^McwOxV9IpPUm$#{lC0m*`MUr zs%>*(tnFxC*kx+jJn7msCTmIxr=+YwP4|ZGqGO1y?;3|IJ8S4zXG{91lD0_FR1BT& zs@&yt`MiwB0gpuR84Cj@MNg(oWgJV?ut*Ab<&v6;_V3=mJD+`NG@nNC1D6>D)dwo? zLS?=X)-2T#37KQWu+n4Wy{^df%(?TCqaO0V}9F5 z$FQo}zSI~_owfxNpEYf7YC^XC)RYa&bRbkW`7jV*We|eNtYreeR(HlJe$aMh6d29L zy3ssKo%y{dpn^iwgfk;K#40IN(J~srj594MV`LhxNM%b{ZE*J9_3z6ED$FC@FcB1F zWK>uThKo*lxgJ|g3$su$IY-i}tPK#Y<_pX2UBrS)I^5U%xdIPDY)L2qa z*E&|m@$w2Pul&=r=yOm**`4QE(VLeKyVj>DIcj2pzy%oc3W`q0VaobMSz`h=fL2C{ zp)H#ORE88SnZ{^b!4qtmnU-1Korrn!V=r6@4oQiTlnlKlxY9425))+=LNDH~6q}Mk zWr>;uEKnoUmP4xQMju7^EKXS_hJYwP8%8Zv&Belm)$IVmNOL zFR^r67#bKlOxCfDK1L-=Siwwu?8jo=jvRqx*o#vqoSbzit57=%Ud(uMf=|-modUKd ztfVKbGPj#5VIvu4R${5e(BaV|jwC6TAVt_>CGx0USLxY)f~lpNcBAtsf`Jo(fg958FK-VPBA*t;Bc;g3E1NHGo@;2HYg#|ov|%pNG8b+w zHE+7obGfGimO^4v@PdD-i3>yu&0DAYe~$kcpKaea)4uOc`-g?C-G#_UMe%?`pyNjW zukoAl+0LGs&YnA+hYB5^6e7Jvv9BaHU+TXSzZ{>9Zkvg2yAzH5F78-(6WCqa!ubMU z4}LXx;mrAXNoXiE_7#Q0rRduwv29lDni0Dey`C2Tx%i(V*U(lHBZa1&MX_rx6ny|V zGt--qPXXQAU=WSSWy^q(R9v;ozIA7$gusVxU(qi z1kDFbe!=T;^ewK?_rapr^J?mw76tR6;B%x}w?e8{$&0{h?-zx=bM>J`h#4+cPnrOb zDEw?8Lk->b!G)kwCqFnjrkpO8698fFODE`Va%2nZBltZQ4`_yLsrVpy2Zrn#r(5B- k;N^M#K39L2i`?bv|MK{G&m#_gi|aVPZPB0M`LKiJZ*oW^$p8QV literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..311f483c6f8a90ca5b8a1a25a225b093d9496221 GIT binary patch literal 3812 zcmeHK-ES0C6u+}OyPa-7cDLQ4sK6C!uuv8-5*3Y5TPlz&G=QKR$Y$8N?ap>SmV58C z?52&Fn1~69kQgCBllr6v6JB}nFVL55SVJ@HgHd02tG34IljqLPbhq;9$BT)R?3^?A zWXK4c za#l7Y*@zj&v-KM ztJo80O*s?Ry0wVbJtOf%&{|9dT2nr__sjS-AIn*}C8ETPTwK$%5opD=f!37Qe04Q$ zEw++i>xt(0K>G`})&+C^x>rrSFVy9S@$TN)>1o>F_u}39z`LdlX8e8L@s*gh-oP5{ zn}5pGREw<#@43UrGrp*_I|e$&)-b8{shDIWa1TaA@p+aHXIceq{GuvP3AXY~sVm#_&*H zc-GXMKGpK2^Qz*9Z~EnyN-$|f;4%dQ*y>3jN{Wp zgk-9aIgv@*q4@xKM-<)fKmKTS&Mcb?Q21yicErPkk=?i=Z|7#IGMV09&`h93K3B3C z503RTD`3&TeF_o}D8g*$vc~lZhkD6j+kHl`mH7>NPA?B7=|0k7f626l{paD4dD#%sn2oc(*3}tUeCjmIt6`ug8UZQ16jx(dW_P!_~A9l&BonEfsh?)u;l#>T~J= zpkQ^J1A9$%Qee_7E_h62{_vs7#vx;+XfRC9lDxwS5V~0_k6lk zb`|h5$DxN}Fe6-L({O)3hw5_YB0}A7N0$+b>}^|)qDcFD2j4k({>-}>=&N>()Z~5j z)H8Ku?JXreucVj4p}y$3%ufpHTw7O?)t+rNCA|<&{iyU_EY7W)i&s-SYRb;VC`zn3 zx4$Xcr=$ht>|!LGh(dD=rJnj3#UoqKx7C$IHF=_@yjfQ|KZv~_ySVd0muTzlpF1&k z;Pc##H*XxQCSR{9`|HUkFR#C}exb8>p=ZrP&tnV8zJ_mD)U?+I%xL@U60CaRa!!-2Z2M4%g(d0H48mW$+R45kM!Z ziOn_n*}5FRxaG>JD~GFz!J547yLjKDq0I%PbSKw;l801y@419_sjctP0 lVpx)-A5h0_l)Q~Peho#X&@TvHOWjCXyA*v(k`kVgKLA&BrjP&t literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..17ddd4057d67f1ce8962858be19fd21d8fe90766 GIT binary patch literal 5046 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: Initiates Request + thunder->>ds: Processes Call + ds->>hal: Forwards to HAL + hal->>vendor: Sends to Vendor + vendor-->>hal: Device/API Configuration + hal-->>ds: Response + ds-->>thunder: Response + thunder-->>curl: Response + + curl->>vComponent: Add Device/API Configurations + vComponent-->>curl: Acknowledge + vendor->>vComponent: Control Plane Interaction + vComponent-->>vendor: Update Device Network +``` + +## Control Plane Commands + +The Control Plane sends messages to the vComponent in `YAML` format. +These commands configure and update the internal `HDMI`-`CEC` device network maintained by vComponent. +Each command is identified by the `hdmicec.command` field and has associated parameters. + +### Supported Commands + +#### Device Network Configuration + +- **Command:** `configure` +- **Purpose:** Initialize the `HDMI` `CEC` device network and vComponent device details. +- **Action in vComponent:** + - Creates the root emulated device (e.g., TV). + - Builds the initial device network hierarchy with connected child devices. + - Resets any previous network state. +- **YAML Example:** [hdmicec_device_config_add_network.yaml](../../vcomponent_configurations/commands/hdmicec_device_config_add_network.yaml), [hdmicec_device_config.yaml](../../vcomponent_configurations/commands/hdmicec_device_config.yaml) + +```yaml +HdmiCec: + command: configure + description: Initialize HDMI CEC device map + config: + emulated_device: + name: "VTV" + language: "eng" + cec_version: "1.4" + device_type: "TV" + power_status: "on" + port_id: 0 + fault: no + number_of_ports: 4 + active_source: false + device_map: + - device: + name: "VTV" + language: "eng" + cec_version: "1.4" + device_type: "TV" + power_status: "on" + fault: no + port_id: 0 + number_of_ports: 4 + active_source: false + children: + - device: + name: "YAMAHA" + language: "eng" + cec_version: "1.4" + device_type: "AudioSystem" + power_status: "on" + fault: no + port_id: 3 + number_of_ports: 2 + active_source: false + children: [] +``` +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent (e.g., `configure`, `add_device`, `remove_device`, `update_device_status`). + - **config:** + (For `configure` command) Contains the initial configuration for the emulated device and the device network. + + - **emulated_device:** + The root device to be emulated + - **name:** Name of the device. + - **language:** Language code (e.g.,`eng`). + - **cec_version:** HDMI CEC version (`unknown`, `1.2`, `1.2a`, `1.3`, `1.3a`, `1.4`, `2.0`). + - **device_type:** Type of device (`TV`, `PlaybackDevice`, `AudioSystem`, `RecordingDevice`, `Tuner`, `Reserved`). + - **power_status:** Power state (`on`, `standby`, `standbyToOn`, `OnToStandby`). + - **port_id:** Port number for the device. + - **fault:** Fault status (`yes`, `partial`, `no`). + - **number_of_ports:** Number of HDMI ports. + - **active_source:** Whether the device is the active source (`true`/`false`). + + - **device_map:** + List of devices in the network, each with the same fields as `emulated_device`, plus: + - **children:** List of child devices (recursive structure). +#### Add Device to Network + +- **Command:** `add_device` +- **Purpose**: Add a new `HDMI` `CEC` device under an existing parent in the device network. +- **Action in vComponent:** + - Creates and attaches a new virtual device. + - Updates internal network topology. +- **YAML Example:** [hdmicec_device_add.yaml](../../vcomponent_configurations/commands/hdmicec_device_add.yaml) +```yaml +HdmiCec: + command: add_device + description: Add a new HDMI CEC device to the device map + device: + name: "GameConsole" + parent: "VTV" + language: "eng" + cec_version: "1.4" + device_type: "PlaybackDevice" + power_status: on + fault: no + port_id: 1 + number_of_ports: 0 + active_source: false +``` + +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + - **device:** + - **name:** Name of the device. + - **language:** Language code (e.g.,`eng`). + - **cec_version:** HDMI CEC version (`unknown`, `1.2`, `1.2a`, `1.3`, `1.3a`, `1.4`, `2.0`). + - **device_type:** Type of device (`TV`, `PlaybackDevice`, `AudioSystem`, `RecordingDevice`, `Tuner`, `Reserved`). + - **power_status:** Power state (`on`, `standby`, `standbyToOn`, `OnToStandby`). + - **port_id:** Port number for the device. + - **fault:** Fault status (`yes`, `partial`, `no`). + - **number_of_ports:** Number of HDMI ports. + - **active_source:** Whether the device is the active source (`true`/`false`). + +#### Remove Device from Network + +- **Command:** `remove_device` +- **Purpose**: Remove an existing `HDMI` `CEC` device from the device network. +- **Action in vComponent:** + - Locates the device by name. + - Removes it from the network hierarchy. +- **YAML Example:** [hdmicec_device_remove.yaml](../../vcomponent_configurations/commands/hdmicec_device_remove.yaml) +```yaml +HdmiCec: + command: remove_device + description: Remove an HDMI CEC device from the device network + device: + name: "GameConsole" +``` +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + - **device.name:** Name of the device to be removed from the network + +#### Update Device Status + +- **Command:** `update_device_status` +- **Purpose**: Updates the power status and device status of an existing device. +- **Action in vComponent:** + - Locates the device by name. + - Updates power status, fault state. +- **YAML Example:** [hdmicec_device_status.yaml](../../vcomponent_configurations/commands/hdmicec_device_status.yaml) +```yaml +HdmiCec: + command: update_device_status + description: Updates the status of an HDMI CEC device + device: + name: "GameConsole" + power_status: "off" + fault: "yes" +``` + +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + - **device.name:** + - **name:** Name of the device to be updated + - **power_status:** Power state (`on`, `standby`, `standbyToOn`, `OnToStandby`). + - **fault:** Fault status (`yes`, `partial`, `no`). + +#### Update Bus Status +- **Command:** `update_bus_status` +- **Purpose**: Updates the CEC bus status +- **Action in vComponent:** + - Updates bus status. +- **YAML Example:** [hdmicec_device_bus_status.yaml](../../vcomponent_configurations/commands/hdmicec_device_bus_status.yaml) +```yaml +HdmiCec: + command: update_bus_status + description: Updates the status of an HDMI CEC bus + status: "idle" +``` +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + - **status:** Bus status (`idle`, `busy`) + +#### Send CEC message to the Device + +- **Command:** `cec_message` +- **Purpose**: Sends a `cec` message asynchronously to the device network. +- **Action in vComponent:** + - Locates the source and destination devices by name. + - If destination is either emulated device or the message is broadcast then triggers a call-back with formatted `cec` message +- **YAML Example:** [hdmicec_device_cec_message.yaml](../../vcomponent_configurations/commands/hdmicec_device_cec_message.yaml) +```yaml +HdmiCec: + command: cec_message + description: Send a CEC message + message: + user_defined: false + source: "YAMAHA" + destination: "VTV" + opcode: "CecVersion" + type: "Direct" + payload: ["cec_version"] + #payload: ["0x50", "0x82", "0x10", "0x00"] +``` + +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + - **message:** + - **user_defined:** If `true`, the payload format is direct message in bytes, if `false` vComponent compose the message based on fields given + - **source:** Name of the source device which sent `cec` message + - **destination:** Name of the destination device + - **opcode:** The `HDMI`-`CEC` operation code (e.g., `GiveOsdName`, `ActiveSource`). + - **type:** `Direct` → point-to-point message, `Broadcast` → message sent to all devices. + - **payload:** A list of parameter names (e.g., ["power_status"], ["physical_address"]). These will be filled in response message. + +#### Prints the device network + +- **Command:** `print` +- **Purpose**: prints the device network. This is used for debugging +- **Action in vComponent:** + - prints the device network. +- **YAML Example:** [hdmicec_device_print.yaml](../../vcomponent_configurations/commands/hdmicec_device_print.yaml) +```yaml +HdmiCec: + command: print + description: Print the current HDMI CEC device map +``` + +- **YAML Field Descriptions** + - **HdmiCec:** The root key for all HDMI CEC control plane commands. + - **command:** The action to be performed by the vComponent. + +## vComponent Device Configuration + +This `YAML` file is used to configure the `HDMI` `CEC` vComponent, which acts as the Device Under Test (DUT) in integration and validation scenarios. The configuration defines the emulated device's properties, its operational parameters. Refer [hdmicec_vcomponent_configuration.yaml](../../vcomponent_configurations/hdmicec_vcomponent_configuration.yaml) + +**YAML Example:** + +```yaml +HdmiCec: + name: "VTV" + language: "eng" + cec_version: "1.4" + device_type: "TV" + power_status: "on" + fault: no + + controllers: + ut_controller_port: 8080 + +# CEC responses +include_0: vcomponent_configurations/hdmicec_vcomponent_cec_responses.yaml +``` + +**YAML Field Descriptions** +- **name** The name of the emulated HDMI CEC device (e.g., "VTV"). +- **language** The language code for the device (e.g., "eng" for English) +- **cec_version** The HDMI CEC protocol version implemented by the device (e.g., "1.4"). +- **device_type** The type of device being emulated ("TV", "AudioSystem", "PlaybackDevice", "Tuner", "RecordingDevice"). +- **power_status** The initial power state of the emulated device. +- **fault** Indicates whether the device should start in a fault state. +- **ut_controller_port** The TCP port number on which the UT (Unit Test) controller communicates with the vComponent. +- **include_0** Path to an external YAML file that defines CEC command–response mappings. + +## CEC Command–Response Mapping (YAML) + +The vComponent uses a `YAML` configuration file to define how it responds to incoming `HDMI` `CEC` messages. Refer [hdmicec_vcomponent_cec_responses.yaml](../../vcomponent_configurations/hdmicec_vcomponent_cec_responses.yaml) + +**Behaviour in vComponent** + +On receiving a request via `AIDL` `sendMessage`, vComponent: + +- Parses the incoming opcode. +- Matches it against the `YAML` command–response table. +- If a response is defined, substitutes runtime values (from device network state) into the payload. +- Sends the response back to the client via `AIDL` call-back `onMessageReceived`. +- If a response is not defined, vComponent will not send a response. +- Based on device status defined in device network, `vComponent` returns status back to client via `AIDL` call-back `onMessageSent` + +**Summary Table for Status Codes:** + +|Bus Status|Message Type|Destination Device Status|`sendMessage` Status|`onMessageSent` Status| +|----------|------------|-------------------------|--------------------|----------------------| +|Busy|`NA`|`NA`|`BUSY`|`BUSY`| +|Idle|Direct|No Fault|`ACK_STATE_0`|`ACK_STATE_0`| +|Idle|Direct|Partial Fault|`ACK_STATE_0`|`ACK_STATE_0`| +|Idle|Direct|Faulty|`ACK_STATE_1`|`ACK_STATE_1`| +|Idle|Broadcast|All of the connected device are working|`ACK_STATE_1`|`ACK_STATE_1`| +|Idle|Broadcast|Any one of the connected device is faulty|`ACK_STATE_0`|`ACK_STATE_0`| + + +The `YAML` file specifies a mapping between: + +- **Request**: an opcode received from a client. +- **Response**: the opcode (and payload, if applicable) that vComponent should return. + +**YAML Structure** +```yaml +HdmiCec: + cec_messages: + - request: { opcode: "", type: "", payload: } + response: { opcode: "", type: "", payload: } +``` + +- **opcode:** The `HDMI`-`CEC` operation code (e.g., `GiveOsdName`, `ActiveSource`). + +- **type:** + - `Direct` → point-to-point message. + - `Broadcast` → message sent to all devices. + +- **payload:** + - null → no payload required. + - A list of parameter names (e.g., ["power_status"], ["physical_address"]). These will be filled in response message. + +**Example Mappings** + +- Simple pass-through with no response +```yaml +- request: { opcode: "Standby", type: "Direct", payload: null } + response: null +``` + +- Query/Response → If a client asks for the OSD name, vComponent replies with a `SetOsdName` containing its configured `osd_name`. +```yaml +- request: { opcode: "Standby", type: "Direct", payload: null } + response: null +``` +## References + +- [`HDMI` `CEC` `AIDL` Interface](https://github.com/rdkcentral/rdk-halif-aidl/tree/0.13.1/hdmicec/current/com/rdk/hal/hdmicec) +- [UT Controller](https://github.com/rdkcentral/ut-control/tree/1.6.6) \ No newline at end of file diff --git a/Tests/vDeviceTests/ledIndicator/TCID001_indicator.py b/Tests/vDeviceTests/ledIndicator/TCID001_indicator.py new file mode 100644 index 00000000..39fdd11a --- /dev/null +++ b/Tests/vDeviceTests/ledIndicator/TCID001_indicator.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import ledIndicatorApis + + +def run_test(): + expected_output_response = { + "jsonrpc": 2.0, + "id": 0, + "result": { + "state": "LEDSTATE_NONE" + } +} + + + log_info("Executing the curl command get led states - Retrieves current state of the LED. e.g. {“state”:”WPS_CONNECTING”}") + + curl_response = send_curl_command( + ledIndicatorApis.get_led_state + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID001 Passed ✅") + return True + else: + log_error("TCID001 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID001 Failed ❌") + return False diff --git a/Tests/vDeviceTests/ledIndicator/TCID002_indicator.py b/Tests/vDeviceTests/ledIndicator/TCID002_indicator.py new file mode 100644 index 00000000..ce8f92a4 --- /dev/null +++ b/Tests/vDeviceTests/ledIndicator/TCID002_indicator.py @@ -0,0 +1,47 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import ledIndicatorApis + + +def run_test(): + expected_output_response = { + "jsonrpc": 2.0, + "id": 1, + "result": { + "supportedLEDStates": [ + "['ACTIVE', 'STANDBY', 'WPS_CONNECTING', 'WPS_CONNECTED', 'WPS_ERROR', 'FACTORY_RESET', 'USB_UPGRADE', 'DOWNLOAD_ERROR']" + ], + "success": True + } +} + + log_info("Executing the curl command get supported let states - Returns the list of LED states that are actually supported by the platform at runtime. Possible values include NONE, ACTIVE, STANDBY, WPS_CONNECTING, WPS_CONNECTED, WPS_ERROR, FACTORY_RESET, USB_UPGRADE and DOWNLOAD_ERROR") + + curl_response = send_curl_command( + ledIndicatorApis.get_supported_led_states + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID002 Passed ✅") + return True + else: + log_error("TCID002 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID002 Failed ❌") + return False diff --git a/Tests/vDeviceTests/ledIndicator/TCID003_indicator.py b/Tests/vDeviceTests/ledIndicator/TCID003_indicator.py new file mode 100644 index 00000000..09b5cb17 --- /dev/null +++ b/Tests/vDeviceTests/ledIndicator/TCID003_indicator.py @@ -0,0 +1,45 @@ +import json +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import ledIndicatorApis + + +def run_test(): + expected_output_response = { + "jsonrpc": 2.0, + "id": 2, + "result": { + "success": True + } +} + + + log_info("Executing the curl command get supported let states - Returns the list of LED states that are actually supported by the platform at runtime. Possible values include NONE, ACTIVE, STANDBY, WPS_CONNECTING, WPS_CONNECTED, WPS_ERROR, FACTORY_RESET, USB_UPGRADE and DOWNLOAD_ERROR") + + curl_response = send_curl_command( + ledIndicatorApis.set_led_state + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID003 Passed ✅") + return True + else: + log_error("TCID003 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID003 Failed ❌") + return False diff --git a/Tests/vDeviceTests/ledIndicator/TCID004_indicator.py b/Tests/vDeviceTests/ledIndicator/TCID004_indicator.py new file mode 100644 index 00000000..d5ed94cc --- /dev/null +++ b/Tests/vDeviceTests/ledIndicator/TCID004_indicator.py @@ -0,0 +1,73 @@ +import json +import subprocess +import time +from utils import ( + send_curl_command, + log_info, + log_success, + log_error, + log_warning +) +import ledIndicatorApis + + +def run_test(): + expected_output_response = { + "jsonrpc": 2.0, + "id": 2, + "result": { + "success": True + } +} + + base_dir = "/tmp" + + log_info("Executing the curl command get supported let states - Returns the list of LED states that are actually supported by the platform at runtime. Possible values include NONE, ACTIVE, STANDBY, WPS_CONNECTING, WPS_CONNECTED, WPS_ERROR, FACTORY_RESET, USB_UPGRADE and DOWNLOAD_ERROR") + + commands = [ + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/indicator_vcomponent_setstates_active.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/indicator_vcomponent_setstates_standby.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/indicator_vcomponent_setstates_usbcontrol.yaml 8080", + "./hdmicec_post_command.sh /tmp/vcomponent_configurations/commands/indicator_vcomponent_setstates_wpsconnected.yaml 8080", + ] + + for command in commands: + log_info("setting LED states throughvComponent") + time.sleep(3) + log_info(f"Running command: {command} in directory: {base_dir}") + result = subprocess.run( + command, + shell=True, + check=False, + text=True, + cwd=base_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE + ) + log_info(f"Command output: {result.stdout.strip()}") + log_info(f"Command error (if any): {result.stderr.strip()}") + log_success(result.stdout.strip()) + + curl_response = send_curl_command( + ledIndicatorApis.set_led_state + ) + + if not curl_response: + log_error("✖ curl command not sent") + return False + time.sleep(3) + + log_success("✔ curl command sent") + log_warning(f"Response: {curl_response}") + + try: + if json.loads(curl_response) == expected_output_response: + log_success("TCID003 Passed ✅") + return True + else: + log_error("TCID003 Failed ❌") + return False + except json.JSONDecodeError: + log_error("Invalid JSON response") + log_error("TCID003 Failed ❌") + return False diff --git a/Tests/vDeviceTests/ledIndicator/__pycache__/TCID001_indicator.cpython-312.pyc b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID001_indicator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b5748d4fd5a30debf3d53cf37adead904be03b2 GIT binary patch literal 1460 zcmY)uO>Y}TbY{Q2_S)Grjavs*%A%Gu4vm#wkgyO+>$q(YajM1$)iSbH-l=QX-nC|C zQbR7t4W*#KfljCpvcxYy zLEVN)=`Zdimz2G81ld-p?BaT<>@*stZFy?lsg$br1IN=iMci^35#ojU1!3&q0l#Hp zyJ}a;!*u+ENb>jakf;fl`%}@p*6Wz_;q{9j4j$ z>D`S|W<8h7X7a1K+l;a6&al|MgYV8pv>oP>`Mu@Feet(v#a#3_au1QFV-u7%T;9-p zW_4w0>AG>(B!nf~JNPnxhJVYf@*;YNUq6no+M8y*Y8fAGtmh2Y1m90Gg8A}czKh-@ z(_OW#YT2X?zR|1_FUHzXV%(Bn5a!#7WsX8zU*diBFA z)kI~=%pI3DU0MpFdNKdy1y{nSXBek?)cbIspx$UXgwM0w%klzrr9hW5Zqed;Kpy;Sx6*%MLFl~*Cf5ZcnE z*Hb`_od7U#TX+qCd`CE*ey6J@UZ``=)w#YX#Ff3ZS1O3kbk%e1sl|?(I?|_)CA~d) zwIj`UC4GP4$!Aa2+mqKi(&C8}k>g!W|0exadcX0TcBMVP{HwOyjb3agu63e|N9Qjd zN8{}a3!Uh@N9Pm&G1V8^>~n4QZy+*59wFIL7kpx_qh9@8pFRmO$tg*&BA&)C-;}}A z_cex}$;q47#b-;9;ba)|SM14bqwB<<=wP<~!2HqisbT&k{kHrF`iumauiL5mLBp}! pI{Fa5#jgA(MJ_RPB0>oN0NTHT0)>A7L;VQ=6Mf}v7{`2#{|BCFW|;s0 literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/ledIndicator/__pycache__/TCID002_indicator.cpython-312.pyc b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID002_indicator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4e3e8bf8000e7bd99921cfa5315b85e601fd514 GIT binary patch literal 1772 zcmZ8h&2Jk;6rcUDz5a^x9S4d!QVNNK6SYO+5D?0Tof1^+$Z@D*Qd!&GNxJEJ*P5Aa zK9ov5zyS$~9uQO_`2!Gt1Bdq7iwl+-mK;#Yr8kEZfpTJI?Tu|#+L`y>@4Yu~-h1<& z#p4mczMtQcw+;gU{K*;r6I;aD`;7P==s*`tP~y923Kg*=R-}?tkxOzVPzqFnrJ&H% z36(;+^aUs>yFyBS#hv6*0k@AJOD}5CjDyF?zHmnWXjdF@OnuZ8*!<<1F z+qfy;Rg)S?AIxs~@( z*{8OGKGoiRiwDBKKw>oPBf8=v0@w}H=!HDemecr!G`cVR01m}A76vroqg%Z`)!z37 zUw0qen*adEI?jms7&}|;h$-G7503%bjMZhxUzn+SVP?4xel6rrTgg zS_9icDv{f4`I>#jv%0ta`S{#Iap|+{cp8qc6z6i8`87`7T3#tH0JbQQ^HnL!c9cs zg;!{D&hrbWU;$AFTg0<54ML&40ol2}0==tJsA2?FjXJ7n?soXOv+G$^O_grgxB{6b zb}VXC&@^1O2{G=N2;Nss2N7skn(62W=JL608a8vAhONw|VRv4;_-v-hdKpT?u8gK( zM?N8Yey}^C&L}J9%Y*N_vtiln{>Y+>&X5Ox+YNJQFH%6HYFh-&K!^8RabYQQ_3CxF ztP+BB`10V(F7cvjm|T4L_1@5u#qMnA@ROB%4zl`qZc-75B?yys6|46ROP{{Cp0T$r?|}6pB6L9|h^%); zyxvL%8*{BYOjmbZh1I^ydX?f4<~qiH@{BDH!5@kKqe!$71o1_&A&HkGj2uj!h69P< zX($ZEntbW?FbKpO0Q6|`YXAbed@}g=#|>U>@U&TyC*&!f!H`k05f1Ee%N!gx^8*A2BG1e*?Ch^#CDx7910X@Ec6wKkhBU Ap#T5? literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/ledIndicator/__pycache__/TCID003_indicator.cpython-312.pyc b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID003_indicator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea57799326380bda8b506de31e5a6299e80cc38c GIT binary patch literal 1603 zcmY*Z%WoS+7@vLF8$aT_+&ZYDgIdx!I8hJ?i3p)Q?3AElM~*`kD`>Udog|yCcdeP( zCaF@X2RI-hkpqHCq<;Y7pP;>RalulDaNHb)$WpfUvUyiOtrA5S&dgMN=|mOE8sv=>ecjdp^v_&uv}+lt%=E^7vqEMnbMb z!-xmMu0RsBC$yN+&?0~xmBwG|dpdfWe65Y`3O|C!V#n44XezXB_Jv%B?h2vrF1R}i z08Vu65f5!_Z@KGCi7vf*4ba{&-{wHbb?9|~hglsuH%fM*yR=<7SJ+Lrz_zpkwuEeN zalM^u`UUR}KibBul9l}ECUG5HH+<1D{Rl?Hv#CDFieK19hDRBKkZvHzI{>yj0Inkn ziC3??m?9I}T%tNf1dhWpq8@fg5Mx_}LU#?`D&#{4x}j63V+3`Bdb(}zbmh6T6GYW* zovyjK2AL=J9BS3j1YC3pvF_Li-qUT5ZDcuy?U@J`OT|JC&dgO7K4)~PGE>aYuH@kD z#U*X7R4f*lp?LFxT*#k`g>t!6&cS&WTPm+;<-$^-l7q`jv)c0F&GJmX09miYeCc-a zR%s@$1@7K3tKRYc_ZO?-xa|JOq4QokFn@Q^%uV-WWkl+(L(mlTIKY*;h5Y2?dvH-F zgq84k|Emk?dEK(P`tdjS(+du}vt`0hmr6y*@CnjnW0=1M%%6te$9xwY(=v4G;+eWd z{3JnCV_Gf11@p&(6~08dzsw=`72DNK;-`4tJThDp75L-Lihc%d*O9@X)m)F(J*tJf z`pMuU2t~r13Bt2a=B8Gc3BqJm$ND|XF(>Y>=G`qP*kHAS2%XajBCFlUTy0l?eI)IJ zPtx4?Mxyu4mL#Sl4?laUg2eEl+TR!$Z>kdqsi6}&)#$s?lt&Nc)ZW;m zFCLW|eYvJQek#Y5^kF>p?bO#(d$r%=*BhhLzs08y6PFvATr)9#FnIYSk#1ZXYbM?~ z7|i^~T%X6UK8s)d8%QjW?~rY(V*xYLRB!x|8aj04#uxqlWnp5tQX8&|)mWyxY#yk7};z+2~{Z1{3+8 iNv^QvR1yT?PZ0lCj0oaCfGw?FAY@vRw}dq2UHm_3;*v%H literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/ledIndicator/__pycache__/TCID004_indicator.cpython-312.pyc b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID004_indicator.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dea0c385d8e5789253aaa14373110f757cc1b67a GIT binary patch literal 3087 zcmcH*U2hx5agRKbCw`b;`k>*jL#@W9OiOla)UFcLmPOK55K#gp*EOMlIPp%>(Z@S> zcTX|}3Uz@NZ~&u`gQ5-)2XOn+1P+kb{DI`9C_vRLq+IwAxPI}Q61iyMr_LUECe;8% z^WXz+XLfeJc6MfV{}KxM5qy9Bb*TLJK7{_kCeG*TAbVLr?jsq=oQ4W*$Q3wy?kczd zx-@r%FYpyl!Bg=TycJ);R}l&V*XHdj^vUkupn|`~CHZGeX)fupqD0Zv1C*# zk}g|yWZ_TThO6#MqfPGZ1VS6`9?rflCuREWugp7G7s~z~ z&aS0E-TeWQgLUo$^daBF;d3O*f`fHo9XyvqGGFJY*P)i}b8=>F_`g>_Iq;}sWrOe8 zQMk^RgZuTcSvmY&+M^B$e0TNu-rZdUbVa@^_dRsQ9qI4yRgXsljutxTU}ZST|Nb0_ z4Nu)eLiCWcE=Qde4soa!`u|UQle>F}NA%?`Wrd2wtX2(76#y^6}h68lv1&35b89=QL-Yk$c?Q+ zjH-sN=xj+}QkP9EQPt4NSSNU7Ox0zzBvAtwdzgtr+c7LcWYkqMq8)&{%X_>s6R+Jll9jp z4}QOYm94D%^9q5iBns$=0oVNGRQk-BAB(dRAyC0j9{hG6IV-6eBY${zePBw5l2c{z z&AFMJ2u;FPlZ;_@xx%)fI$^7tqEszEF&C@Yupa|%s9cMmotn*H)^&k}Vzr9<0mmLT zuuxhNurlRT!$egjRtV0a2-Koo44B=km|c$+&zhCx(F{o@R+u@HR!WAfWY~iP!ktiV zRqaD9w!>I-T(yKni6})l9ZPUZ(DHRK9Adgd_VdOOAk3&}e=n|1jxSsz3MLB@mR6x~ zM{h2qjWykNV_{w)bP|-4h2DKEw1ayNo=BZKAFb9b0RmEl7D@4Ip#A{-(k&srnY}-KZ+g4`#8&@_ z$NkBsF!D5!Yy}T*2S>JoBYSSwLI0i5Hv)SchAou zPoxn!(d19I`0(b)`)|KL(}<*+{OMiZ?-^(X!taj1Grn1Q92jn#y!5xgrB-mLkw`Uz zr+4B*PnqJ8X7JQbJn?T}-3}bv3LN_uxj|5fHe$>v8+olMocJ=_zw3jQ7lge?K93#G zy3pr83BdS;E14a2e{q_FF&V(@xqye*z{<_?z!j+xJDu&4XlM7!yv6MGVjua(Xb(_? ze+a`1;f;zRo0{@7JOWepQX}m0-*s~w_Z13!g`zP2%jM-<|3onC9Y9=S&-*$zfRn)X E9}A-(-v9sr literal 0 HcmV?d00001 diff --git a/Tests/vDeviceTests/ledIndicator/__pycache__/ledIndicatorApis.cpython-312.pyc b/Tests/vDeviceTests/ledIndicator/__pycache__/ledIndicatorApis.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6eeeb53bf6fe8bee8d92706892859879d6dd5300 GIT binary patch literal 872 zcmcgrO-chX6rORah)@w%x)4GXL~*9JAlgv`sZ|6~vE#xrP+}A8=*%Q0skRl*;Tb%F zYnR@j8y8-nBDiqno6@4L>dFMd_a%?__q{x)(_;p#kD1iPqGcGb3F$Ah2i_+D+#A#= z8`LbDbf`Skv=&mW$7)@M$hITWuyqhIv;w5Y2xSuC0*^I|we2+pbCG5Zoe?1k;&lv0 zl3mrA(&*^08b6ZF&2Mbm^4YF23Mk`$> z?Wu&Sey_eCR67mvzxjjlo(%8jZo&0W6qCw_bgqM#I+y-7zllRmsPa9S!2(fC`4C|* zra_fxE`O0N5hzDAKSwtrPU|7tl%wD``59^!j*exTW+#;zp6ghKIo_G") + return 1 + + suite_name = normalize_suite_name(sys.argv[1]) + if suite_name not in SUITES: + log_error(f"Unknown suite '{sys.argv[1]}'. Supported suites: HdmiCecSource, ledindicator") + return 1 + + return run_suite(suite_name) + + +if __name__ == "__main__": + raise SystemExit(main()) \ No newline at end of file diff --git a/Tests/vDeviceTests/utils.py b/Tests/vDeviceTests/utils.py new file mode 100644 index 00000000..0ac5d3f6 --- /dev/null +++ b/Tests/vDeviceTests/utils.py @@ -0,0 +1,55 @@ +import os +import json + + + +# ---------- ANSI COLOR CONSTANTS ---------- +RESET = "\033[0m" +BOLD = "\033[1m" + +RED = "\033[91m" +GREEN = "\033[92m" +YELLOW = "\033[93m" +BLUE = "\033[94m" +CYAN = "\033[96m" + +# ---------- OPTIONAL LOG HELPERS ---------- +def log_info(msg): + print(f"{CYAN}{msg}{RESET}") + +def log_success(msg): + print(f"{GREEN}{BOLD}{msg}{RESET}") + +def log_warning(msg): + print(f"{YELLOW}{msg}{RESET}") + +def log_error(msg): + print(f"{RED}{BOLD}{msg}{RESET}") + +def send_curl_command(curl_command): + '''This function is used to send the curl commands to get the output response using os module''' + output_response = "" + try: + # Send the curl command using os.system module + response = os.popen(curl_command) + + # Find the line that is a valid JSON for extracting only the json response + for line in response.readlines(): + try: + # Try to parse the current line as JSON + json.loads(line) + output_response = line + # Exit the loop as we found the JSON line + break + except json.JSONDecodeError: + # If current line is not a valid JSON, just pass and continue with the next line + pass + + # Check the output response and add a message if the obtained output response is null + if len(output_response) < 5: + output_response = "< No response from WPEFramework >" + except: + print("Inside Utils.py : Exception in send_curl_command function") + finally: + # Return the output json response of given curl command as a string + return output_response \ No newline at end of file