1# SPDX-License-Identifier: MIT 2import subprocess 3import time 4from oeqa.core.decorator import OETestTag 5from oeqa.core.decorator.data import skipIfArch 6from oeqa.core.case import OEPTestResultTestCase 7from oeqa.selftest.case import OESelftestTestCase 8from oeqa.utils.commands import runCmd, bitbake, get_bb_var, runqemu 9from oeqa.utils.sshcontrol import SSHControl 10 11def parse_results(filename): 12 tests = {} 13 with open(filename, "r") as f: 14 lines = f.readlines() 15 for line in lines: 16 if "..." in line and "test [" in line: 17 test = line.split("test ")[1].split(" ... ")[0] 18 if "] " in test: 19 test = test.split("] ", 1)[1] 20 result = line.split(" ... ")[1].strip() 21 if result == "ok": 22 result = "PASS" 23 elif result == "failed": 24 result = "FAIL" 25 elif "ignored" in result: 26 result = "SKIPPED" 27 if test in tests: 28 if tests[test] != result: 29 print("Duplicate and mismatching result %s for %s" % (result, test)) 30 else: 31 print("Duplicate result %s for %s" % (result, test)) 32 else: 33 tests[test] = result 34 return tests 35 36# Total time taken for testing is of about 2hr 20min, with PARALLEL_MAKE set to 40 number of jobs. 37@OETestTag("toolchain-system") 38@OETestTag("toolchain-user") 39@OETestTag("runqemu") 40class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase): 41 42 @skipIfArch(['mips', 'mips64']) 43 def test_rust(self, *args, **kwargs): 44 # build remote-test-server before image build 45 recipe = "rust" 46 start_time = time.time() 47 bitbake("{} -c test_compile".format(recipe)) 48 builddir = get_bb_var("RUSTSRC", "rust") 49 # build core-image-minimal with required packages 50 default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp"] 51 features = [] 52 features.append('IMAGE_FEATURES += "ssh-server-dropbear"') 53 features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(default_installed_packages))) 54 self.write_config("\n".join(features)) 55 bitbake("core-image-minimal") 56 57 # Exclude the test folders that error out while building 58 # TODO: Fix the errors and include them for testing 59 # no-fail-fast: Run all tests regardless of failure. 60 # bless: First runs rustfmt to format the codebase, 61 # then runs tidy checks. 62 exclude_list = [ 63 'src/bootstrap', 64 'src/doc/rustc', 65 'src/doc/rustdoc', 66 'src/doc/unstable-book', 67 'src/etc/test-float-parse', 68 'src/librustdoc', 69 'src/rustdoc-json-types', 70 'src/tools/jsondoclint', 71 'src/tools/lint-docs', 72 'src/tools/replace-version-placeholder', 73 'src/tools/rust-analyzer', 74 'src/tools/rustdoc-themes', 75 'src/tools/rust-installer', 76 'src/tools/suggest-tests', 77 'tests/assembly/asm/aarch64-outline-atomics.rs', 78 'tests/codegen/issues/issue-122805.rs', 79 'tests/codegen/thread-local.rs', 80 'tests/mir-opt/', 81 'tests/run-make', 82 'tests/run-make-fulldeps', 83 'tests/rustdoc', 84 'tests/rustdoc-json', 85 'tests/rustdoc-js-std', 86 'tests/ui/abi/stack-probes-lto.rs', 87 'tests/ui/abi/stack-probes.rs', 88 'tests/ui/codegen/mismatched-data-layouts.rs', 89 'tests/codegen/rust-abi-arch-specific-adjustment.rs', 90 'tests/ui/debuginfo/debuginfo-emit-llvm-ir-and-split-debuginfo.rs', 91 'tests/ui/feature-gates/version_check.rs', 92 'tests/ui-fulldeps/', 93 'tests/ui/process/nofile-limit.rs', 94 'tidyselftest' 95 ] 96 97 exclude_fail_tests = " ".join([" --exclude " + item for item in exclude_list]) 98 # Add exclude_fail_tests with other test arguments 99 testargs = exclude_fail_tests + " --no-fail-fast --bless" 100 101 # wrap the execution with a qemu instance. 102 # Tests are run with 512 tasks in parallel to execute all tests very quickly 103 with runqemu("core-image-minimal", runqemuparams = "nographic", qemuparams = "-m 512") as qemu: 104 # Copy remote-test-server to image through scp 105 host_sys = get_bb_var("RUST_BUILD_SYS", "rust") 106 ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user="root") 107 ssh.copy_to(builddir + "/build/" + host_sys + "/stage1-tools-bin/remote-test-server","~/") 108 # Execute remote-test-server on image through background ssh 109 command = '~/remote-test-server --bind 0.0.0.0:12345 -v' 110 sshrun=subprocess.Popen(("ssh", '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', '-f', "root@%s" % qemu.ip, command), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 111 # Get the values of variables. 112 tcpath = get_bb_var("TARGET_SYS", "rust") 113 targetsys = get_bb_var("RUST_TARGET_SYS", "rust") 114 rustlibpath = get_bb_var("WORKDIR", "rust") 115 tmpdir = get_bb_var("TMPDIR", "rust") 116 117 # Set path for target-poky-linux-gcc, RUST_TARGET_PATH and hosttools. 118 cmd = "export TARGET_VENDOR=\"-poky\";" 119 cmd = cmd + " export PATH=%s/recipe-sysroot-native/usr/bin/python3-native:%s/recipe-sysroot-native/usr/bin:%s/recipe-sysroot-native/usr/bin/%s:%s/hosttools:$PATH;" % (rustlibpath, rustlibpath, rustlibpath, tcpath, tmpdir) 120 cmd = cmd + " export RUST_TARGET_PATH=%s/rust-targets;" % rustlibpath 121 # Trigger testing. 122 cmd = cmd + " export TEST_DEVICE_ADDR=\"%s:12345\";" % qemu.ip 123 cmd = cmd + " cd %s; python3 src/bootstrap/bootstrap.py test %s --target %s" % (builddir, testargs, targetsys) 124 retval = runCmd(cmd) 125 end_time = time.time() 126 127 resultlog = rustlibpath + "/results-log.txt" 128 with open(resultlog, "w") as f: 129 f.write(retval.output) 130 131 ptestsuite = "rust" 132 self.ptest_section(ptestsuite, duration = int(end_time - start_time), logfile=resultlog) 133 test_results = parse_results(resultlog) 134 for test in test_results: 135 self.ptest_result(ptestsuite, test, test_results[test]) 136