From 71f0d20e8f2d0bb380de236a519965909cc0f356 Mon Sep 17 00:00:00 2001 From: Fernando Bravo <39527354+fernando79513@users.noreply.github.com> Date: Wed, 13 Mar 2024 18:50:47 +0100 Subject: [PATCH] Cover smaller genio tests (New) (#1060) * Formatted dvfs test and removed typos * Added test for dvfs_gpu_check_governors * Raise SystemExit only on fail * Added serialcheck tests * Fixed Error raise when stdout is empty * Added spidev test * Added pmic regulator tests * Fixed errors in linux_ccf - Moved check_env_variables to function so the module can be imported without requiring them - Added choices for devices considered in the test - Test failing with wrong verify output * Added linux ccf tests * Update contrib/genio/bin/spidev_test.py Co-authored-by: kissiel --------- Co-authored-by: kissiel --- contrib/genio/bin/dvfs_gpu_check_governors.py | 28 ++-- contrib/genio/bin/linux_ccf.py | 91 ++++++----- contrib/genio/bin/serialcheck.py | 7 +- contrib/genio/bin/spidev_test.py | 5 +- .../tests/test_dvfs_gpu_check_governors.py | 55 +++++++ contrib/genio/tests/test_linux_ccf.py | 141 ++++++++++++++++++ contrib/genio/tests/test_pmic_regulator.py | 66 ++++++++ contrib/genio/tests/test_serialcheck.py | 117 +++++++++++++++ contrib/genio/tests/test_spidev.py | 131 ++++++++++++++++ 9 files changed, 584 insertions(+), 57 deletions(-) create mode 100644 contrib/genio/tests/test_dvfs_gpu_check_governors.py create mode 100644 contrib/genio/tests/test_linux_ccf.py create mode 100644 contrib/genio/tests/test_pmic_regulator.py create mode 100644 contrib/genio/tests/test_serialcheck.py create mode 100644 contrib/genio/tests/test_spidev.py diff --git a/contrib/genio/bin/dvfs_gpu_check_governors.py b/contrib/genio/bin/dvfs_gpu_check_governors.py index 4e6b5aa93..c8c254013 100755 --- a/contrib/genio/bin/dvfs_gpu_check_governors.py +++ b/contrib/genio/bin/dvfs_gpu_check_governors.py @@ -2,41 +2,43 @@ import argparse -GOVERNORS = ['userspace', 'powersave', 'performance', 'simple_ondemand'] -print(f'Expected Governos: {GOVERNORS}') +GOVERNORS = ["userspace", "powersave", "performance", "simple_ondemand"] +print(f"Expected Governors: {GOVERNORS}") def test_sysfs_attrs_read(soc): fail = 0 - mail_type = '13000000.mali' - if soc == 'mt8365': - mail_type = '13040000.mali' + mail_type = "13000000.mali" + if soc == "mt8365": + mail_type = "13040000.mali" node_path = ( - f'/sys/devices/platform/soc/{mail_type}/devfreq/{mail_type}/' - f'available_governors' + f"/sys/devices/platform/soc/{mail_type}/devfreq/{mail_type}/" + f"available_governors" ) with open(node_path) as f: for node in f.read().strip().split(): if node not in GOVERNORS: fail = 1 - print(f"Failed: found governor '{node}' out of expextation") + print( + f"Failed: found governor '{node}' out of expectation" + ) return fail def main(): parser = argparse.ArgumentParser() parser.add_argument( - 'soc', - help='SoC type. e.g mt8395', - choices=['mt8395', 'mt8390', 'mt8365'] + "soc", + help="SoC type. e.g mt8395", + choices=["mt8395", "mt8390", "mt8365"], ) args = parser.parse_args() ret = test_sysfs_attrs_read(args.soc) if ret: exit(1) - print('Pass') + print("Pass") -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/contrib/genio/bin/linux_ccf.py b/contrib/genio/bin/linux_ccf.py index db2d6d08a..29381b6e2 100755 --- a/contrib/genio/bin/linux_ccf.py +++ b/contrib/genio/bin/linux_ccf.py @@ -4,15 +4,8 @@ import argparse import subprocess -PLAINBOX_SESSION_SHARE = os.environ.get('PLAINBOX_SESSION_SHARE') -if not PLAINBOX_SESSION_SHARE: - print("no env var PLAINBOX_SESSION_SHARE") - exit(1) - -PLAINBOX_PROVIDER_DATA = os.environ.get('PLAINBOX_PROVIDER_DATA') -if not PLAINBOX_PROVIDER_DATA: - print("no env var PLAINBOX_PROVIDER_DATA") - exit(1) +PLAINBOX_SESSION_SHARE = os.environ.get("PLAINBOX_SESSION_SHARE") +PLAINBOX_PROVIDER_DATA = os.environ.get("PLAINBOX_PROVIDER_DATA") def runcmd(command): @@ -22,61 +15,81 @@ def runcmd(command): stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", - timeout=1 + timeout=1, ) return ret +def check_env_variables(): + if not PLAINBOX_SESSION_SHARE: + print("no env var PLAINBOX_SESSION_SHARE") + exit(1) + if not PLAINBOX_PROVIDER_DATA: + print("no env var PLAINBOX_PROVIDER_DATA") + exit(1) + + def test_linux_ccf(soc): - if soc == 'mt8365': - print('mt8365 is not supported') + if soc == "mt8365": + print("mt8365 is not supported") exit(1) clk_summary_path = f"{PLAINBOX_SESSION_SHARE}/clk-summary.txt" cat_ret = runcmd( - [f"cat /sys/kernel/debug/clk/clk_summary | tee {clk_summary_path}"]) + [f"cat /sys/kernel/debug/clk/clk_summary | tee {clk_summary_path}"] + ) if cat_ret.returncode: - print(f'Failed: unable to dump clk_summary data to {clk_summary_path}') + print(f"Failed: unable to dump clk_summary data to {clk_summary_path}") exit(1) - print('Dump /sys/kernel/debug/clk/clk_summary:') + print("Dump /sys/kernel/debug/clk/clk_summary:") print(cat_ret.stdout) - if soc == 'mt8390': - verify_ret = runcmd([ - ( - f"verify-mt8188-ccf.sh" - f" -t {PLAINBOX_PROVIDER_DATA}/linux-ccf/mt8188-clk.h" - f" -s {clk_summary_path}" - ) - ]) - elif soc == 'mt8395' or soc == 'mt8195': - verify_ret = runcmd([ - ( - f"verify-mt8195-ccf.sh" - f" -t {PLAINBOX_PROVIDER_DATA}/linux-ccf/mt8195-clk.h" - f" -s {clk_summary_path}" - ) - ]) + if soc == "mt8390": + verify_ret = runcmd( + [ + ( + f"verify-mt8188-ccf.sh" + f" -t {PLAINBOX_PROVIDER_DATA}/linux-ccf/mt8188-clk.h" + f" -s {clk_summary_path}" + ) + ] + ) + elif soc == "mt8395" or soc == "mt8195": + verify_ret = runcmd( + [ + ( + f"verify-mt8195-ccf.sh" + f" -t {PLAINBOX_PROVIDER_DATA}/linux-ccf/mt8195-clk.h" + f" -s {clk_summary_path}" + ) + ] + ) if verify_ret.returncode: - print(f'Failed: {verify_ret.stdout}') + print(f"Failed: {verify_ret.stdout}") exit(1) - if verify_ret.stdout.split('\n')[0] \ - == '[-] Success, all clocks are mapped !': - print('Test Pass') + if ( + verify_ret.stdout.split("\n")[0] + != "[-] Success, all clocks are mapped !" + ): + print(f"Wrong output: {verify_ret.stdout}") + exit(1) + + print("Test Pass") def main(): parser = argparse.ArgumentParser() parser.add_argument( - 'soc', - help='SoC type. e.g mt8395', - choices=['mt8395', 'mt8390'] + "soc", + help="SoC type. e.g mt8395", + choices=["mt8395", "mt8195", "mt8390", "mt8390"], ) args = parser.parse_args() + check_env_variables() test_linux_ccf(args.soc) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/contrib/genio/bin/serialcheck.py b/contrib/genio/bin/serialcheck.py index 2468fb8f3..cd363fbf2 100755 --- a/contrib/genio/bin/serialcheck.py +++ b/contrib/genio/bin/serialcheck.py @@ -36,17 +36,18 @@ def test_uart_by_serialcheck(soc): 38400, 19200, 9600, 4800, 2400, 1200, 600, 300, 110 ] - fail = 0 + fail = False for br in available_baudrate: print('\n' + '*' * 80) print(f'Testing baudrate: {br}\n') ret = runcmd([cmd.format(tty_node, file_path, br)]) print(ret.stdout) if ret.returncode != 0 or ret.stdout.split('\n')[-2] != golden_msg: - fail = 1 + fail = True print('Fail: the output doesn\'t match the golden sample') - raise SystemExit(fail) + if fail: + raise SystemExit(1) def main(): diff --git a/contrib/genio/bin/spidev_test.py b/contrib/genio/bin/spidev_test.py index d4816cba5..1af658b83 100755 --- a/contrib/genio/bin/spidev_test.py +++ b/contrib/genio/bin/spidev_test.py @@ -43,10 +43,11 @@ def test_spi_content_consistency(platform): spi_ret = runcmd([cmd]) print(spi_ret.stdout) - packets = spi_ret.stdout.split('\n') - if not len(packets): + if not spi_ret.stdout: raise SystemExit( 'ERROR: no any output be reported') + + packets = spi_ret.stdout.split('\n') for rx, tx in zip(packets[-2:-1], packets[-3:-2]): tx_content = tx.split('|')[2] rx_content = rx.split('|')[2] diff --git a/contrib/genio/tests/test_dvfs_gpu_check_governors.py b/contrib/genio/tests/test_dvfs_gpu_check_governors.py new file mode 100644 index 000000000..b0702f3c4 --- /dev/null +++ b/contrib/genio/tests/test_dvfs_gpu_check_governors.py @@ -0,0 +1,55 @@ +import unittest +from unittest.mock import mock_open, patch +import dvfs_gpu_check_governors as dvfs + + +class TestDvfsGpuCheckGovernors(unittest.TestCase): + + def test_all_expected_governors(self): + # Test when all expected governors are present + governors = "userspace powersave performance simple_ondemand" + with patch("builtins.open", mock_open(read_data=governors)): + result = dvfs.test_sysfs_attrs_read("mt8365") + self.assertEqual(result, 0) + + with patch("builtins.open", mock_open(read_data=governors)): + result = dvfs.test_sysfs_attrs_read("mt8364") + self.assertEqual(result, 0) + + def test_unexpected_governor(self): + # Test when an unexpected governor is present + governors = "userspace powersave performance unexpected_governor" + with patch("builtins.open", mock_open(read_data=governors)): + result = dvfs.test_sysfs_attrs_read("mt8365") + self.assertEqual(result, 1) + + @patch("builtins.open", mock_open(read_data="")) + def test_empty_file(self): + # Test when the file is empty + governors = "" + with patch("builtins.open", mock_open(read_data=governors)): + result = dvfs.test_sysfs_attrs_read("mt8365") + self.assertEqual(result, 0) + + @patch("dvfs_gpu_check_governors.test_sysfs_attrs_read") + def test_main(self, mock_attrs_read): + mock_attrs_read.return_value = 0 + with patch("sys.argv", ["script_name", "mt8395"]): + result = dvfs.main() + self.assertEqual(mock_attrs_read.call_count, 1) + self.assertEqual(result, None) + + @patch("dvfs_gpu_check_governors.test_sysfs_attrs_read") + def test_main_bad_args(self, mock_attrs_read): + with patch("sys.argv", ["script_name", "bad_soc"]): + with self.assertRaises(SystemExit): + dvfs.main() + self.assertEqual(mock_attrs_read.call_count, 0) + + @patch("dvfs_gpu_check_governors.test_sysfs_attrs_read") + def test_main_wrong_attrs(self, mock_attrs_read): + mock_attrs_read.return_value = 1 + with patch("sys.argv", ["script_name", "mt8395"]): + with self.assertRaises(SystemExit): + dvfs.main() + self.assertEqual(mock_attrs_read.call_count, 1) diff --git a/contrib/genio/tests/test_linux_ccf.py b/contrib/genio/tests/test_linux_ccf.py new file mode 100644 index 000000000..59551accc --- /dev/null +++ b/contrib/genio/tests/test_linux_ccf.py @@ -0,0 +1,141 @@ +import unittest +from unittest.mock import patch, MagicMock +import linux_ccf as ccf + + +class TestLinuxCCF(unittest.TestCase): + @patch("linux_ccf.subprocess.run") + def test_runcmd(self, mock_run): + mock_run.return_value = MagicMock( + stdout="output", stderr="error", returncode=0 + ) + result = ccf.runcmd("echo Hello") + self.assertEqual(result.stdout, "output") + self.assertEqual(result.stderr, "error") + self.assertEqual(result.returncode, 0) + + @patch("linux_ccf.PLAINBOX_SESSION_SHARE", "/share") + @patch("linux_ccf.PLAINBOX_PROVIDER_DATA", "/tmp") + def test_check_env_variables(self): + self.assertEqual(ccf.check_env_variables(), None) + + @patch("linux_ccf.PLAINBOX_SESSION_SHARE", "") + @patch("linux_ccf.PLAINBOX_PROVIDER_DATA", "/tmp") + def test_check_session_share_not_defined(self): + with self.assertRaises(SystemExit): + ccf.check_env_variables() + + @patch("linux_ccf.PLAINBOX_SESSION_SHARE", "/share") + @patch("linux_ccf.PLAINBOX_PROVIDER_DATA", "") + def test_check_provider_data_not_defined(self): + with self.assertRaises(SystemExit): + ccf.check_env_variables() + + @patch("linux_ccf.runcmd") + def test_test_linux_ccf(self, mock_runcmd): + mock_runcmd.side_effect = [ + MagicMock(returncode=0), + MagicMock( + stdout="[-] Success, all clocks are mapped !", + stderr="", + returncode=0, + ), + ] + ccf.test_linux_ccf("mt8390") + mock_runcmd.assert_called() + + def test_test_linux_ccf_fails_with_mt8365(self): + with self.assertRaises(SystemExit): + ccf.test_linux_ccf("mt8365") + + @patch("linux_ccf.runcmd") + def test_test_linux_ccf_fail_clk_summary(self, mock_runcmd): + mock_runcmd.return_value = MagicMock( + stdout="", + stderr="error", + returncode=1, + ) + with self.assertRaises(SystemExit): + ccf.test_linux_ccf("mt8390") + + @patch("linux_ccf.runcmd") + @patch("linux_ccf.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("linux_ccf.PLAINBOX_SESSION_SHARE", "/share") + def test_test_linux_ccf_mt8390(self, mock_runcmd): + mock_runcmd.side_effect = [ + MagicMock(returncode=0), + MagicMock( + stdout="[-] Success, all clocks are mapped !", + stderr="", + returncode=0, + ), + ] + ccf.test_linux_ccf("mt8390") + mock_runcmd.assert_called_with( + [ + "verify-mt8188-ccf.sh -t /tmp/linux-ccf/mt8188-clk.h" + " -s /share/clk-summary.txt" + ] + ) + + @patch("linux_ccf.runcmd") + def test_test_linux_ccf_fail_verify(self, mock_runcmd): + mock_runcmd.side_effect = [ + MagicMock(returncode=0), + MagicMock(returncode=1), + ] + with self.assertRaises(SystemExit): + ccf.test_linux_ccf("mt8390") + + @patch("linux_ccf.runcmd") + def test_test_linux_ccf_fail_verify_wrong_output(self, mock_runcmd): + mock_runcmd.side_effect = [ + MagicMock(returncode=0), + MagicMock(stdout="", returncode=0), + ] + with self.assertRaises(SystemExit): + ccf.test_linux_ccf("mt8390") + + @patch("linux_ccf.runcmd") + @patch("linux_ccf.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("linux_ccf.PLAINBOX_SESSION_SHARE", "/share") + def test_test_linux_ccf_mt8395_or_mt8195(self, mock_runcmd): + mock_runcmd.side_effect = [ + MagicMock(returncode=0), + MagicMock( + stdout="[-] Success, all clocks are mapped !", + stderr="", + returncode=0, + ), + ] + cmd = [ + "verify-mt8195-ccf.sh -t /tmp/linux-ccf/mt8195-clk.h" + " -s /share/clk-summary.txt" + ] + ccf.test_linux_ccf("mt8195") + mock_runcmd.assert_called_with(cmd) + + @patch("linux_ccf.check_env_variables") + @patch("linux_ccf.test_linux_ccf") + def test_main(self, mock_test_linux_ccf, mock_check_env): + with patch("sys.argv", ["soc", "mt8395"]): + result = ccf.main() + self.assertEqual(mock_test_linux_ccf.call_count, 1) + self.assertEqual(result, None) + + @patch("linux_ccf.check_env_variables") + @patch("linux_ccf.test_linux_ccf") + def test_main_bad_args(self, mock_test_linux_ccf, mock_check_env): + with patch("sys.argv", ["script_name", "bad_soc"]): + with self.assertRaises(SystemExit): + ccf.main() + mock_test_linux_ccf.assert_not_called() + + @patch("linux_ccf.check_env_variables") + @patch("linux_ccf.test_linux_ccf") + def test_main_wrong_ccf(self, mock_test_linux_ccf, mock_check_env): + mock_test_linux_ccf.side_effect = SystemExit(1) + with patch("sys.argv", ["script_name", "mt8395"]): + with self.assertRaises(SystemExit): + ccf.main() + mock_test_linux_ccf.assert_called_once_with("mt8395") diff --git a/contrib/genio/tests/test_pmic_regulator.py b/contrib/genio/tests/test_pmic_regulator.py new file mode 100644 index 000000000..60f69d028 --- /dev/null +++ b/contrib/genio/tests/test_pmic_regulator.py @@ -0,0 +1,66 @@ +import unittest +from unittest.mock import patch, mock_open +import pmic_regulator + + +class TestRegulator(unittest.TestCase): + + @patch("os.path.exists") + @patch("builtins.open", new_callable=mock_open, read_data="attr_1") + def test_read_attr(self, mock_file, mock_exists): + mock_exists.return_value = True + result = pmic_regulator.read_attr("attribute") + self.assertEqual(result, "attr_1") + + @patch("os.path.exists") + @patch("builtins.open", new_callable=mock_open, read_data="") + def test_read_attr_not_exists(self, mock_file, mock_exists): + mock_exists.return_value = False + result = pmic_regulator.read_attr("attribute") + self.assertEqual(result, "") + + @patch("pmic_regulator.read_attr") + def test_read_all_name(self, mock_read_attr): + mock_read_attr.side_effect = ["node1", "node2", ""] + result = pmic_regulator.read_all_name() + self.assertEqual(result, {"node1", "node2"}) + + @patch("pmic_regulator.read_all_name") + def test_regulator(self, mock_read_all_name): + mock_read_all_name.return_value = pmic_regulator.mt8365_MAIN_REGULATORS + result = pmic_regulator.test_regulator("mt8365") + self.assertEqual(result, None) + + @patch("pmic_regulator.read_all_name") + def test_regulator_mt8390(self, mock_read_all_name): + mock_read_all_name.return_value = pmic_regulator.MAIN_REGULATORS + result = pmic_regulator.test_regulator("mt8390") + self.assertEqual(result, None) + + @patch("pmic_regulator.read_all_name") + def test_regulator_missing_node(self, mock_read_all_name): + mock_read_all_name.return_value = ["wrong_node"] + with self.assertRaises(SystemExit): + pmic_regulator.test_regulator("mt8365") + + @patch("pmic_regulator.test_regulator") + def test_main(self, mock_test_regulator): + with patch("sys.argv", ["script_name", "mt8395"]): + result = pmic_regulator.main() + self.assertEqual(mock_test_regulator.call_count, 1) + self.assertEqual(result, None) + + @patch("pmic_regulator.test_regulator") + def test_main_bad_args(self, mock_test_regulator): + with patch("sys.argv", ["script_name", "bad_soc"]): + with self.assertRaises(SystemExit): + pmic_regulator.main() + mock_test_regulator.assert_not_called() + + @patch("pmic_regulator.test_regulator") + def test_main_wrong_serialcheck(self, mock_test_regulator): + mock_test_regulator.side_effect = SystemExit(1) + with patch("sys.argv", ["script_name", "mt8395"]): + with self.assertRaises(SystemExit): + pmic_regulator.main() + mock_test_regulator.assert_called_once_with("mt8395") diff --git a/contrib/genio/tests/test_serialcheck.py b/contrib/genio/tests/test_serialcheck.py new file mode 100644 index 000000000..40a29cc44 --- /dev/null +++ b/contrib/genio/tests/test_serialcheck.py @@ -0,0 +1,117 @@ +import unittest +from unittest.mock import patch, MagicMock +import serialcheck as sc + + +class TestSerialCheck(unittest.TestCase): + + @patch("serialcheck.subprocess.run") + def test_runcmd(self, mock_run): + mock_run.return_value = MagicMock( + stdout="output", stderr="error", returncode=0 + ) + result = sc.runcmd("echo Hello") + + mock_run.assert_called_once() + self.assertEqual(result.stdout, "output") + self.assertEqual(result.stderr, "error") + self.assertEqual(result.returncode, 0) + + @patch("serialcheck.runcmd") + @patch("os.environ.get") + def test_uart_by_sc(self, mock_get, mock_runcmd): + mock_get.return_value = "/tmp" + + # Mock the runcmd function to return the correct message + msg = ( + "cts: 0 dsr: 0 rng: 0 dcd: 0 rx: 12288 " + "tx: 12288 frame 0 ovr 0 par: 0 brk: 0 buf_ovrr: 0\n" + ) + # The first command is to copy the file, so we don't need the output + results = [""] + [MagicMock(stdout=msg, stderr="", returncode=0)] * 17 + mock_runcmd.side_effect = results + + self.assertEqual(sc.test_uart_by_serialcheck("mt8390"), None) + mock_runcmd.assert_called_with( + [ + "genio-test-tool.serialcheck -d /dev/ttyS2 -f /tmp/binary " + "-m d -l 3 -b 110" + ], + ) + + @patch("serialcheck.runcmd") + @patch("os.environ.get") + def test_uart_by_sc_mt8395(self, mock_get, mock_runcmd): + mock_get.return_value = "/tmp" + + # Mock the runcmd function to return the correct message + msg = ( + "cts: 0 dsr: 0 rng: 0 dcd: 0 rx: 12288 " + "tx: 12288 frame 0 ovr 0 par: 0 brk: 0 buf_ovrr: 0\n" + ) + # The first command is to copy the file, so we don't need the output + results = [""] + [MagicMock(stdout=msg, stderr="", returncode=0)] * 17 + mock_runcmd.side_effect = results + + self.assertEqual(sc.test_uart_by_serialcheck("mt8395"), None) + mock_runcmd.assert_called_with( + [ + "genio-test-tool.serialcheck -d /dev/ttyS1 -f /tmp/binary " + "-m d -l 3 -b 110" + ], + ) + + @patch("serialcheck.runcmd") + @patch("os.environ.get") + def test_uart_by_sc_bad_return_code(self, mock_get, mock_runcmd): + mock_get.return_value = "/tmp" + + # Mock the runcmd function to return a wrong message + msg = ( + "cts: 0 dsr: 0 rng: 0 dcd: 0 rx: 12288 " + "tx: 12288 frame 0 ovr 0 par: 0 brk: 0 buf_ovrr: 0\n" + ) + # The first command is to copy the file, so we don't need the output + results = [""] + [MagicMock(stdout=msg, stderr="", returncode=1)] * 17 + mock_runcmd.side_effect = results + + with self.assertRaises(SystemExit): + sc.test_uart_by_serialcheck("mt8395") + + @patch("serialcheck.runcmd") + @patch("os.environ.get") + def test_uart_by_sc_wrong_output(self, mock_get, mock_runcmd): + mock_get.return_value = "/tmp" + + # Mock the runcmd function to return a wrong message + msg = "output\nBad message\nend output" + # The first command is to copy the file, so we don't need the output + results = [""] + [MagicMock(stdout=msg, stderr="", returncode=0)] * 17 + mock_runcmd.side_effect = results + + with self.assertRaises(SystemExit): + sc.test_uart_by_serialcheck("mt8395") + + @patch("serialcheck.test_uart_by_serialcheck") + def test_main(self, mock_serialcheck): + mock_serialcheck.return_value = 0 + with patch("sys.argv", ["script_name", "mt8395"]): + result = sc.main() + self.assertEqual(mock_serialcheck.call_count, 1) + self.assertEqual(result, None) + + @patch("serialcheck.test_uart_by_serialcheck") + def test_main_bad_args(self, mock_serialcheck): + mock_serialcheck.return_value = 1 + with patch("sys.argv", ["script_name", "bad_soc"]): + with self.assertRaises(SystemExit): + sc.main() + mock_serialcheck.assert_not_called() + + @patch("serialcheck.test_uart_by_serialcheck") + def test_main_wrong_serialcheck(self, mock_serialcheck): + mock_serialcheck.side_effect = SystemExit(1) + with patch("sys.argv", ["script_name", "mt8395"]): + with self.assertRaises(SystemExit): + sc.main() + self.assertEqual(mock_serialcheck.call_count, 1) diff --git a/contrib/genio/tests/test_spidev.py b/contrib/genio/tests/test_spidev.py new file mode 100644 index 000000000..949d43154 --- /dev/null +++ b/contrib/genio/tests/test_spidev.py @@ -0,0 +1,131 @@ +import unittest +from unittest.mock import patch, MagicMock +import spidev_test as spidev + + +class TestSpidev(unittest.TestCase): + + @patch("spidev_test.subprocess.run") + def test_runcmd(self, mock_run): + mock_run.return_value = MagicMock( + stdout="output", stderr="error", returncode=0 + ) + result = spidev.runcmd("echo Hello") + + mock_run.assert_called_once() + self.assertEqual(result.stdout, "output") + self.assertEqual(result.stderr, "error") + self.assertEqual(result.returncode, 0) + + @patch("spidev_test.os.path.exists") + def test_check_spi_node(self, mock_exists): + mock_exists.return_value = True + result = spidev.check_spi_node("/dev/spidev0.0") + self.assertEqual(result, None) + + @patch("spidev_test.os.path.exists") + def test_check_spi_node_fail(self, mock_exists): + mock_exists.return_value = False + with self.assertRaises(SystemExit): + spidev.check_spi_node("/dev/spidev0.0") + + @patch("spidev_test.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("spidev_test.runcmd") + @patch("spidev_test.check_spi_node") + def test_test_spi_content(self, mock_check_spi, mock_runcmd): + mock_check_spi.return_value = None + mock_runcmd.return_value = MagicMock( + stdout=( + "TX | FF FF FF FF FF FF | ......\n" + "RX | FF FF FF FF FF FF | ......\n" + ), + stderr="", + returncode=0, + ) + + result = spidev.test_spi_content_consistency("G1200-evk") + self.assertEqual(result, None) + mock_runcmd.assert_called_with( + [ + "genio-test-tool.spidev-test -D /dev/spidev1.0 -s 400000 -i " + "/tmp/spi/test.bin -v", + ], + ) + + @patch("spidev_test.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("spidev_test.runcmd") + @patch("spidev_test.check_spi_node") + def test_test_spi_content_G700(self, mock_check_spi, mock_runcmd): + mock_check_spi.return_value = None + mock_runcmd.return_value = MagicMock( + stdout=( + "TX | FF FF FF FF FF FF | ......\n" + "RX | FF FF FF FF FF FF | ......\n" + ), + stderr="", + returncode=0, + ) + + result = spidev.test_spi_content_consistency("G700") + self.assertEqual(result, None) + mock_runcmd.assert_called_with( + [ + "genio-test-tool.spidev-test -D /dev/spidev0.0 -s 400000 -i " + "/tmp/spi/test.bin -v", + ], + ) + + @patch("spidev_test.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("spidev_test.runcmd") + @patch("spidev_test.check_spi_node") + def test_test_spi_content_no_packets(self, mock_check_spi, mock_runcmd): + mock_check_spi.return_value = None + mock_runcmd.return_value = MagicMock( + stdout="", + stderr="", + returncode=0, + ) + with self.assertRaises(SystemExit): + spidev.test_spi_content_consistency("G1200-evk") + + @patch("spidev_test.PLAINBOX_PROVIDER_DATA", "/tmp") + @patch("spidev_test.runcmd") + @patch("spidev_test.check_spi_node") + def test_test_spi_content_no_consistency( + self, mock_check_spi, mock_runcmd + ): + mock_check_spi.return_value = None + mock_runcmd.return_value = MagicMock( + stdout=( + "TX | FF FF FF FF FF FF | ......\n" + "RX | 31 31 31 31 31 31 | 111111\n" + ), + stderr="", + returncode=0, + ) + with self.assertRaises(SystemExit): + spidev.test_spi_content_consistency("G1200-evk") + + @patch("spidev_test.test_spi_content_consistency") + def test_main(self, mock_spi_content): + mock_spi_content.return_value = 0 + with patch("sys.argv", ["platform", "G1200-evk"]): + result = spidev.main() + self.assertEqual(mock_spi_content.call_count, 1) + self.assertEqual(result, None) + + @patch("spidev_test.test_spi_content_consistency") + def test_main_bad_args(self, mock_spi_content): + mock_spi_content.return_value = 1 + with patch("sys.argv", ["script_name", "bad_soc"]): + with self.assertRaises(SystemExit): + spidev.main() + mock_spi_content.assert_not_called() + + @patch("spidev_test.test_spi_content_consistency") + def test_main_wrong_serialcheck(self, mock_spi_content): + mock_spi_content.side_effect = SystemExit(1) + with patch("sys.argv", ["script_name", "G1200-evk"]): + with self.assertRaises(SystemExit): + spidev.main() + self.assertEqual(mock_spi_content.call_count, 1)