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 00000000..7b211686 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/HdmiCecSourceApis.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc new file mode 100644 index 00000000..b345d726 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID001.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc new file mode 100644 index 00000000..194f0252 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID002.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc new file mode 100644 index 00000000..0358ce0f Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID003.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID004.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID004.cpython-312.pyc new file mode 100644 index 00000000..5561823f Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID004.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID005.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID005.cpython-312.pyc new file mode 100644 index 00000000..c8c0eed3 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID005.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID006.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID006.cpython-312.pyc new file mode 100644 index 00000000..319bcf98 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID006.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc new file mode 100644 index 00000000..f9b391bd Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID007.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc new file mode 100644 index 00000000..fc2b4441 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID008.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc new file mode 100644 index 00000000..5512d917 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID009.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc new file mode 100644 index 00000000..b40a0148 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID010.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID011.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID011.cpython-312.pyc new file mode 100644 index 00000000..95c6b2b2 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID011.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc new file mode 100644 index 00000000..1d8b95de Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID012.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID013.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID013.cpython-312.pyc new file mode 100644 index 00000000..21eb1583 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID013.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc new file mode 100644 index 00000000..5ad6b177 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID014.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc new file mode 100644 index 00000000..399770fc Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID018.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc new file mode 100644 index 00000000..285303d3 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID019.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc new file mode 100644 index 00000000..17f49fe1 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID020.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc new file mode 100644 index 00000000..26625f72 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID021.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc new file mode 100644 index 00000000..872c190b Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID022.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc new file mode 100644 index 00000000..d9c2c921 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID023.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc new file mode 100644 index 00000000..311f483c Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/TCID024.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc new file mode 100644 index 00000000..17ddd405 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/suiteManager.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/__pycache__/utils.cpython-312.pyc b/Tests/vDeviceTests/__pycache__/utils.cpython-312.pyc new file mode 100644 index 00000000..07958d47 Binary files /dev/null and b/Tests/vDeviceTests/__pycache__/utils.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/hdmiCec_vcomponent_design.md b/Tests/vDeviceTests/hdmiCec_vcomponent_design.md new file mode 100644 index 00000000..4911b385 --- /dev/null +++ b/Tests/vDeviceTests/hdmiCec_vcomponent_design.md @@ -0,0 +1,392 @@ +# HDMI CEC vComponent Design Document + +## Table of Contents + +- [Acronyms, Terms and Abbreviations](#acronyms-terms-and-abbreviations) +- [Introduction](#introduction) +- [Sequence Flow](#sequence-flow) +- [Control Plane Commands](#control-plane-commands) +- [CEC Command–Response Mapping](#cec-commandresponse-mapping-yaml) +- [References](#references) + +## Acronyms, Terms and Abbreviations + +- `HAL` - Hardware Abstraction Layer +- `API` - Application Programming Interface +- `AIDL` - Android Interface Definition Language +- `VTS` - Vendor Test Suite +- `HDMI` - High-Definition Multimedia Interface +- `CEC` - Consumer Electronics Control +- `YAML` - Yet Another Markup Language + +## Introduction + +The `HDMI` `CEC` vComponent is a virtual service that simulates an `HDMI` `CEC` device network. + +It is designed to: + +- Receive control/configuration commands from the vDevice Controller via the Control Plane. + +- Expose a `HDMI` `CEC` `HAL` interface to clients (such as `VTS`) via `AIDL`. + +- Process and respond to `CEC` messages according to predefined behaviour defined in `YAML` configuration files. + +This allows integration testing, validation, and automation without requiring physical `HDMI` `CEC` hardware. + +## Sequence Flow + +This section illustrates the typical interaction sequence between the client (such as `VTS`), the `AIDL` interface, the `HDMI` `CEC` vComponent service, the Control Plane, and the vDevice Controller. The flow diagram below details the configuration, registration, message exchange, and device management steps involved in simulating an `HDMI` `CEC` device network for integration testing and validation. + +```mermaid +sequenceDiagram + participant curl as curl Command (Test Suite) + participant thunder as Thunder Call + participant ds as DS Layer + participant hal as HAL (Client) + participant vendor as Vendor Server + participant vComponent as vComponent (Control Plane) + + curl->>thunder: 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 00000000..1b5748d4 Binary files /dev/null and b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID001_indicator.cpython-312.pyc differ 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 00000000..b4e3e8bf Binary files /dev/null and b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID002_indicator.cpython-312.pyc differ 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 00000000..ea577993 Binary files /dev/null and b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID003_indicator.cpython-312.pyc differ 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 00000000..dea0c385 Binary files /dev/null and b/Tests/vDeviceTests/ledIndicator/__pycache__/TCID004_indicator.cpython-312.pyc differ 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 00000000..6eeeb53b Binary files /dev/null and b/Tests/vDeviceTests/ledIndicator/__pycache__/ledIndicatorApis.cpython-312.pyc differ diff --git a/Tests/vDeviceTests/ledIndicator/ledIndicatorApis.py b/Tests/vDeviceTests/ledIndicator/ledIndicatorApis.py new file mode 100644 index 00000000..78549e33 --- /dev/null +++ b/Tests/vDeviceTests/ledIndicator/ledIndicatorApis.py @@ -0,0 +1,23 @@ +get_led_state = ( + 'curl --max-time 5 ' + '--header "Content-Type: text/plain;" ' + '--request POST ' + '--data-binary \'{"jsonrpc": 2.0, "id": 0, "method": "org.rdk.LEDControl.getLEDState"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + +get_supported_led_states = ( + 'curl --max-time 5 ' + '--header "Content-Type: text/plain;" ' + '--request POST ' + '--data-binary \'{"jsonrpc": 2.0, "id": 1, "method": "org.rdk.LEDControl.getSupportedLEDStates"}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) + +set_led_state = ( + 'curl --max-time 5 ' + '--header "Content-Type: text/plain;" ' + '--request POST ' + '--data-binary \'{"jsonrpc": 2.0, "id": 2, "method": "org.rdk.LEDControl.setLEDState", "params": {"state": "FACTORY_RESET"}}\' ' + 'http://127.0.0.1:9998/jsonrpc' +) diff --git a/Tests/vDeviceTests/suiteManager.py b/Tests/vDeviceTests/suiteManager.py new file mode 100644 index 00000000..08ef7df4 --- /dev/null +++ b/Tests/vDeviceTests/suiteManager.py @@ -0,0 +1,139 @@ +import importlib +import io +import sys +import time +from pathlib import Path + +from utils import log_error, log_info, log_success + + +BASE_DIR = Path(__file__).resolve().parent +SUITES = { + "hdmicecsource": { + "banner": "******************** L2 SUITE - RDK - HDMI CEC SOURCE ****************************", + "module_dir": BASE_DIR, + "tests": [ + "TCID001", + "TCID002", + "TCID003", + "TCID004", + "TCID005", + "TCID006", + "TCID007", + "TCID008", + "TCID009", + "TCID010", + "TCID011", + "TCID012", + "TCID013", + "TCID014", + "TCID022", + "TCID023", + "TCID024", + "TCID021", + "TCID018", + "TCID020", + "TCID019", + ], + }, + "ledindicator": { + "banner": "******************** L2 SUITE - RDK - LED INDICATOR ****************************", + "module_dir": BASE_DIR / "ledIndicator", + "tests": [ + "TCID001_indicator", + "TCID002_indicator", + "TCID003_indicator", + "TCID004_indicator", + ], + }, +} + + +def normalize_suite_name(raw_name): + return raw_name.strip().replace("_", "").replace("-", "").lower() + + +def load_test_cases(suite_name): + suite_config = SUITES[suite_name] + module_dir = str(suite_config["module_dir"]) + + if module_dir not in sys.path: + sys.path.insert(0, module_dir) + + test_cases = [] + for module_name in suite_config["tests"]: + module = importlib.import_module(module_name) + test_cases.append((module_name, module.run_test)) + + return suite_config["banner"], test_cases + + +def run_suite(suite_name): + banner, test_cases = load_test_cases(suite_name) + print(banner) + + passed = 0 + failed = 0 + failed_cases = [] + original_stdout = sys.stdout + + for tc_name, tc_fn in test_cases: + log_info(f"Running {tc_name}") + captured = io.StringIO() + try: + time.sleep(10) + sys.stdout = captured + result = tc_fn() + sys.stdout = original_stdout + output = captured.getvalue() + print(output, end="") + if result: + passed += 1 + else: + failed += 1 + failed_cases.append((tc_name, "Returned False", output.strip())) + except Exception as error: + sys.stdout = original_stdout + output = captured.getvalue() + print(output, end="") + log_error(f"{tc_name} Crashed ❌ | Error: {error}") + failed += 1 + failed_cases.append((tc_name, f"Exception: {error}", output.strip())) + + print("\n==================== L2 SUITE SUMMARY ====================") + log_success(f"Passed : {passed}") + log_error(f"Failed : {failed}") + print(f"Total : {passed + failed}") + + if failed_cases: + print("Failed Cases :") + for tc_name, _, _ in failed_cases: + log_error(f" ❌ {tc_name}") + + print("Failed Remarks :") + for tc_name, reason, output in failed_cases: + log_error(f" ❌ {tc_name} | {reason}") + if output: + log_error(f" Output : {output}") + else: + print("Failed Cases : None") + + print("==========================================================") + return 0 if failed == 0 else 1 + + +def main(): + if len(sys.argv) != 2: + log_error("Usage: python3 suiteManager.py ") + 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