diff options
Diffstat (limited to 'meta-arm/lib/oeqa/runtime')
-rw-r--r-- | meta-arm/lib/oeqa/runtime/cases/ftpm.py | 41 | ||||
-rw-r--r-- | meta-arm/lib/oeqa/runtime/cases/fvp_boot.py | 25 | ||||
-rw-r--r-- | meta-arm/lib/oeqa/runtime/cases/fvp_devices.py | 130 | ||||
-rw-r--r-- | meta-arm/lib/oeqa/runtime/cases/optee.py | 24 | ||||
-rw-r--r-- | meta-arm/lib/oeqa/runtime/cases/trusted_services.py | 104 |
5 files changed, 324 insertions, 0 deletions
diff --git a/meta-arm/lib/oeqa/runtime/cases/ftpm.py b/meta-arm/lib/oeqa/runtime/cases/ftpm.py new file mode 100644 index 00000000..be0cf46f --- /dev/null +++ b/meta-arm/lib/oeqa/runtime/cases/ftpm.py @@ -0,0 +1,41 @@ +# +# SPDX-License-Identifier: MIT +# + +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.oetimeout import OETimeout + +class FtpmTestSuite(OERuntimeTestCase): + """ + Minimal test for optee-ftpm and ftpm kernel driver interfaces + """ + @OETimeout(360) + def test_ftpm(self): + # device files, need tee-supplicant fully initialized which takes some time + # and tests seem to run before boot is complete + cmd = "ls -l /dev/tpm0 /dev/tpmrm0 || ( runlevel; sleep 60; ls -l /dev/tpm0 /dev/tpmrm0 )" + status, output = self.target.run(cmd, timeout=90) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) + + # tpm version + cmd = "cat /sys/class/tpm/tpm0/tpm_version_major" + status, output = self.target.run(cmd, timeout=60) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) + self.assertEqual(output, "2", msg='\n'.join([cmd, output])) + + # sha384 pcrs + cmd = 'for c in $(seq 0 23); do cat /sys/class/tpm/tpm0/pcr-sha384/"${c}"; done' + status, output = self.target.run(cmd, timeout=60) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) + + # sha256 pcrs + cmd = 'for c in $(seq 0 23); do cat /sys/class/tpm/tpm0/pcr-sha256/"${c}"; done' + status, output = self.target.run(cmd, timeout=60) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) + + # sha1 pcrs + cmd = 'for c in $(seq 0 23); do cat /sys/class/tpm/tpm0/pcr-sha1/"${c}"; done' + status, output = self.target.run(cmd, timeout=60) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) diff --git a/meta-arm/lib/oeqa/runtime/cases/fvp_boot.py b/meta-arm/lib/oeqa/runtime/cases/fvp_boot.py new file mode 100644 index 00000000..342186eb --- /dev/null +++ b/meta-arm/lib/oeqa/runtime/cases/fvp_boot.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: MIT + +from oeqa.runtime.case import OERuntimeTestCase + +class FVPBootTest(OERuntimeTestCase): + """ + This test waits for a Linux login prompt on the default console. It is + dependent on the OEFVPTarget test controller + """ + + def test_fvp_boot(self): + import pexpect + + self.target.transition("off") + timeout = int(self.td.get('TEST_FVP_LINUX_BOOT_TIMEOUT') or 10*60) + self.target.transition("linux", timeout) + + # Check for common error patterns on all consoles + for console in self.target.config['consoles']: + # "expect" a timeout when searching for the error patterns + match = self.target.expect(console, + [br'(\[ERR\]|\[ERROR\]|ERROR\:)', + pexpect.TIMEOUT], + timeout=0) + self.assertEqual(match, 1) diff --git a/meta-arm/lib/oeqa/runtime/cases/fvp_devices.py b/meta-arm/lib/oeqa/runtime/cases/fvp_devices.py new file mode 100644 index 00000000..0246e76a --- /dev/null +++ b/meta-arm/lib/oeqa/runtime/cases/fvp_devices.py @@ -0,0 +1,130 @@ +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.data import skipIfNotInDataVar +from oeqa.core.decorator.depends import OETestDepends + + +class FvpDevicesTest(OERuntimeTestCase): + def run_cmd(self, cmd, check=True): + """ + A wrapper around self.target.run, which: + * Fails the test on command failure by default + * Allows the "run" behavior to be overridden in sub-classes + """ + (status, output) = self.target.run(cmd) + if status and check: + self.fail("Command '%s' returned non-zero exit " + "status %d:\n%s" % (cmd, status, output)) + + return (status, output) + + def check_devices(self, cls, min_count, search_drivers): + # Find all the devices of the specified class + cmd = f'find "/sys/class/{cls}" -type l -maxdepth 1' + _, output = self.run_cmd(cmd) + + devices = output.split() + self.assertGreaterEqual(len(devices), + min_count, + msg='Device count is lower than expected') + + # Assert that at least one of the devices uses at least one of the + # drivers + drivers = set() + for device in devices: + cmd = f'basename "$(readlink "{device}/device/driver")"' + _, output = self.run_cmd(cmd) + drivers.update(output.split()) + + self.assertTrue(drivers & set(search_drivers), + msg='No device uses either of the drivers: ' + + str(search_drivers)) + + def check_rng(self, hw_random, dev): + cmd = f'cat {hw_random} | grep {dev}' + self.run_cmd(cmd) + + def set_cpu(self, cpu_num, flag): + # Issue echo command + self.run_cmd( + f'echo "{flag}" > "/sys/devices/system/cpu/cpu{cpu_num}/online"', + check = False, + ) + _, output = self.run_cmd( + f'cat "/sys/devices/system/cpu/cpu{cpu_num}/online"' + ) + + return output == flag + + def enable_cpu(self, cpu_num): + return self.set_cpu(cpu_num, "1") + + def disable_cpu(self, cpu_num): + return self.set_cpu(cpu_num, "0") + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @skipIfNotInDataVar('TEST_FVP_DEVICES', 'cpu_hotplug', + 'cpu_hotplug not included in BSP tests') + def test_cpu_hotplug(self): + _, cpus = self.run_cmd('find /sys/firmware/devicetree/base/cpus/' + ' -name "cpu@*" -maxdepth 1 | wc -l') + + try: + count_cpus = int(cpus) + except ValueError: + self.fail(f"Expected number of CPUs, but found this:\n{cpus}") + + self.num_cpus = int(self.td.get('TEST_CPU_HOTPLUG_NUM_CPUS', + count_cpus)) + try: + # Test that all cores are online + _, cpus = self.run_cmd('grep -c "processor" /proc/cpuinfo') + self.assertEqual(int(cpus), self.num_cpus) + # Don't try to disable here the only cpu present in the system. + if self.num_cpus > 1: + # Test that we can stop each core individually + for i in range(self.num_cpus): + self.assertTrue(self.disable_cpu(i)) + self.assertTrue(self.enable_cpu(i)) + + # Test that we cannot disable all cores + for i in range(self.num_cpus - 1): + self.assertTrue(self.disable_cpu(i)) + # Disabling last core should trigger an error + self.assertFalse(self.disable_cpu(self.num_cpus - 1)) + finally: + # Ensure all CPUs are re-enabled + for i in range(self.num_cpus): + self.enable_cpu(i) + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @skipIfNotInDataVar('TEST_FVP_DEVICES', 'rtc', + 'rtc device not included in BSP tests') + def test_rtc(self): + self.check_devices("rtc", 1, ["rtc-pl031"]) + self.run_cmd('hwclock') + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @skipIfNotInDataVar('TEST_FVP_DEVICES', 'watchdog', + 'watchdog device not included in BSP tests') + def test_watchdog(self): + self.check_devices("watchdog", 1, ["sp805-wdt", "sbsa-gwdt"]) + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @skipIfNotInDataVar('TEST_FVP_DEVICES', 'networking', + 'networking device not included in BSP tests') + def test_networking(self): + self.check_devices("net", 2, ["virtio_net", "vif"]) + + # Check that outbound network connections work + self.run_cmd('wget -O /dev/null "https://www.arm.com"') + + @OETestDepends(['ssh.SSHTest.test_ssh']) + @skipIfNotInDataVar('TEST_FVP_DEVICES', 'virtiorng', + 'virtiorng device not included in BSP tests') + def test_virtiorng(self): + self.check_rng('/sys/devices/virtual/misc/hw_random/rng_available', + 'virtio_rng.0') + self.check_rng('/sys/devices/virtual/misc/hw_random/rng_current', + 'virtio_rng.0') + + self.run_cmd('hexdump -n 32 /dev/hwrng') diff --git a/meta-arm/lib/oeqa/runtime/cases/optee.py b/meta-arm/lib/oeqa/runtime/cases/optee.py new file mode 100644 index 00000000..4f46225b --- /dev/null +++ b/meta-arm/lib/oeqa/runtime/cases/optee.py @@ -0,0 +1,24 @@ +# +# SPDX-License-Identifier: MIT +# + +import os + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.runtime.decorator.package import OEHasPackage +from oeqa.core.decorator.oetimeout import OETimeout + +class OpteeTestSuite(OERuntimeTestCase): + """ + Run OP-TEE tests (xtest). + """ + @OETimeout(1300) + @OEHasPackage(['optee-test']) + def test_opteetest_xtest(self): + # clear storage before executing tests + cmd = "xtest --clear-storage || true" + status, output = self.target.run(cmd, timeout=60) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) + cmd = "xtest" + status, output = self.target.run(cmd, timeout=1200) + self.assertEqual(status, 0, msg='\n'.join([cmd, output])) diff --git a/meta-arm/lib/oeqa/runtime/cases/trusted_services.py b/meta-arm/lib/oeqa/runtime/cases/trusted_services.py new file mode 100644 index 00000000..54423999 --- /dev/null +++ b/meta-arm/lib/oeqa/runtime/cases/trusted_services.py @@ -0,0 +1,104 @@ +# + +from oeqa.runtime.case import OERuntimeTestCase +from oeqa.core.decorator.depends import OETestDepends +from oeqa.runtime.decorator.package import OEHasPackage +from oeqa.core.decorator.data import skipIfNotInDataVar + +class TrustedServicesTest(OERuntimeTestCase): + + def run_test_tool(self, cmd, expected_status=0, expected_output=None ): + """ Run a test utility """ + + status, output = self.target.run(cmd) + self.assertEqual(status, expected_status, msg='\n'.join([cmd, output])) + if expected_output is not None: + self.assertEqual(output, expected_output, msg='\n'.join([cmd, output])) + + @OEHasPackage(['ts-demo']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_00_ts_demo(self): + self.run_test_tool('ts-demo') + + @OEHasPackage(['ts-uefi-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_02_ts_uefi_test(self): + self.run_test_tool('uefi-test') + + @OEHasPackage(['ts-psa-crypto-api-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_03_psa_crypto_api_test(self): + self.run_test_tool('psa-crypto-api-test') + + @OEHasPackage(['ts-psa-its-api-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_04_psa_its_api_test(self): + self.run_test_tool('psa-its-api-test') + + @OEHasPackage(['ts-psa-ps-api-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_05_psa_ps_api_test(self): + self.run_test_tool('psa-ps-api-test') + + @OEHasPackage(['ts-psa-iat-api-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_06_psa_iat_api_test(self): + self.run_test_tool('psa-iat-api-test') + + @OEHasPackage(['ts-service-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_09_ts_service_grp_check(self): + # If this test fails, available test groups in ts-service-test have changed and all + # tests using the test executable need to be double checked to ensure test group to + # TS SP mapping is still valid. + test_grp_list="FwuServiceTests PsServiceTests ItsServiceTests AttestationProvisioningTests" + test_grp_list+=" AttestationServiceTests CryptoKeyDerivationServicePackedcTests" + test_grp_list+=" CryptoMacServicePackedcTests CryptoCipherServicePackedcTests" + test_grp_list+=" CryptoHashServicePackedcTests CryptoServicePackedcTests" + test_grp_list+=" CryptoServiceProtobufTests CryptoServiceLimitTests" + self.run_test_tool('ts-service-test -lg', expected_output=test_grp_list) + + @OEHasPackage(['optee-test']) + @skipIfNotInDataVar('MACHINE_FEATURES', 'optee-spmc-test', 'SPMC Test SPs are not included') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_07_spmc_test(self): + self.run_test_tool('xtest -t ffa_spmc') + + @OEHasPackage(['ts-service-test']) + @skipIfNotInDataVar('MACHINE_FEATURES', 'ts-fwu', 'FWU SP is not included') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_10_fwu_service_tests(self): + self.run_test_tool('ts-service-test -g FwuServiceTests') + + @OEHasPackage(['ts-service-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_11_ps_service_tests(self): + if 'ts-storage' not in self.tc.td['MACHINE_FEATURES'] and \ + 'ts-se-proxy' not in self.tc.td['MACHINE_FEATURES']: + self.skipTest('Storage SP is not deployed in the system.') + self.run_test_tool('ts-service-test -g PsServiceTests') + + @OEHasPackage(['ts-service-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_12_its_service_tests(self): + if 'ts-its' not in self.tc.td['MACHINE_FEATURES'] and \ + 'ts-se-proxy' not in self.tc.td['MACHINE_FEATURES']: + self.skipTest('Internal Storage SP is not deployed in the system.') + self.run_test_tool('ts-service-test -g ItsServiceTests') + + @OEHasPackage(['ts-service-test']) + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_14_attestation_service_tests(self): + if 'ts-attestation' not in self.tc.td['MACHINE_FEATURES'] and \ + 'ts-se-proxy' not in self.tc.td['MACHINE_FEATURES']: + self.skipTest('Attestation SP is not deployed in the system.') + self.run_test_tool('ts-service-test -g Attestation') + + @OEHasPackage(['ts-service-test']) + @skipIfNotInDataVar('MACHINE_FEATURES', 'ts-crypto', 'Crypto SP is not included') + @OETestDepends(['ssh.SSHTest.test_ssh']) + def test_15_crypto_service_tests(self): + if 'ts-crypto' not in self.tc.td['MACHINE_FEATURES'] and \ + 'ts-se-proxy' not in self.tc.td['MACHINE_FEATURES']: + self.skipTest('Crypto SP is not deployed in the system.') + self.run_test_tool('ts-service-test -g Crypto') |