oeqa/selftest: Add rust selftests

The patch implements Rust testing framework similar to other selftest,
specifically the gcc selftest in OE. It uses the client and server
based method to test the binaries for cross-target on the image.
The test framework is a wrapper around the Rust build system as ./x.py
test. It tests many functionalities of Rust distribution like tools,
documentation, libraries, packages, tools, Cargo, Crater etc.
Please refer the following link for detailed description of Rust
testing:-
https://rustc-dev-guide.rust-lang.org/tests/intro.html#tool-tests

To support the rust tests in oe-core, the following functions were
added:-
setup_cargo_environment(): Build bootstrap and some early stage tools.
do_rust_setup_snapshot(): Install the snapshot version of rust binaries.
do_configure(): To generate config.toml
do_compile(): To build "remote-test-server" for qemu target image.

Approximate Number of Tests Run in the Rust Testsuite :- 18000
Approximate Number of Tests that FAIL in bitbake environment :- 100-150
Normally majority of the testcases are present in major folder "test/"
It contributes to more than 80% of the testcases present in Rust test
framework. These tests pass as expected on any Rust versions without
much fuss. The tests that fail are of less important and contribute to
less than 2% of the total testcases. These minor tests are observed to
work on some versions and fail on others. They have to be added, ignored
or excluded for different versions as per the behavior.
These tests have been ignored or excluded in the Rust selftest
environment to generate success of completing the testsuite.

These tests work in parallel mode even in the skipped test mode as
expected. Although the patch to disable tests is large, it is very simple
in that it only disables tests. When updating to a newer version of Rust,
the patch can usually be ported in a day.

Tested for X86, X86-64, ARM, ARM64 and MIPS64 on Ubuntu 22.04.
(From OE-Core rev: 7c3346d8fbe85302b605bb3f772b029ea7bfaa6c)

Signed-off-by: pgowda <pgowda.cve@gmail.com>
Signed-off-by: Vinay Kumar <vinay.m.engg@gmail.com>
Signed-off-by: Yash Shinde <yashinde145@gmail.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Yash Shinde
2023-07-11 14:33:46 +04:00
committed by Richard Purdie
parent d101e64b1c
commit a1096d4a57
4 changed files with 2416 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
# SPDX-License-Identifier: MIT
import os
import subprocess
from oeqa.core.decorator import OETestTag
from oeqa.core.case import OEPTestResultTestCase
from oeqa.selftest.case import OESelftestTestCase
from oeqa.utils.commands import runCmd, bitbake, get_bb_var, get_bb_vars, runqemu, Command
from oeqa.utils.sshcontrol import SSHControl
def parse_results(filename):
tests = []
with open(filename, "r") as f:
lines = f.readlines()
for line in lines:
if "..." in line and "test [" in line:
test = line.split("test ")[1].split(" ... ")[0]
result = line.split(" ... ")[1].strip()
if result == "ok":
result = "PASS"
elif result == "failed":
result = "FAIL"
elif "ignored" in result:
result = "SKIP"
tests.append((test, result))
return tests
# Total time taken for testing is of about 2hr 20min, with PARALLEL_MAKE set to 40 number of jobs.
class RustSelfTestSystemEmulated(OESelftestTestCase, OEPTestResultTestCase):
def test_rust(self, *args, **kwargs):
# build remote-test-server before image build
recipe = "rust"
bitbake("{} -c test_compile".format(recipe))
builddir = get_bb_var("RUSTSRC", "rust")
# build core-image-minimal with required packages
default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp"]
features = []
features.append('IMAGE_FEATURES += "ssh-server-dropbear"')
features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(default_installed_packages)))
self.write_config("\n".join(features))
bitbake("core-image-minimal")
# wrap the execution with a qemu instance.
# Tests are run with 512 tasks in parallel to execute all tests very quickly
with runqemu("core-image-minimal", runqemuparams = "nographic", qemuparams = "-m 512") as qemu:
# Copy remote-test-server to image through scp
host_sys = get_bb_var("RUST_BUILD_SYS", "rust")
ssh = SSHControl(ip=qemu.ip, logfile=qemu.sshlog, user="root")
ssh.copy_to(builddir + "/build/" + host_sys + "/stage1-tools-bin/remote-test-server","~/")
# Execute remote-test-server on image through background ssh
command = '~/remote-test-server --bind 0.0.0.0:12345 -v'
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)
# Get the values of variables.
tcpath = get_bb_var("TARGET_SYS", "rust")
targetsys = get_bb_var("RUST_TARGET_SYS", "rust")
rustlibpath = get_bb_var("WORKDIR", "rust")
tmpdir = get_bb_var("TMPDIR", "rust")
# Exclude the test folders that error out while building
# TODO: Fix the errors and include them for testing
# no-fail-fast: Run all tests regardless of failure.
# bless: First runs rustfmt to format the codebase,
# then runs tidy checks.
testargs = "--exclude tests/rustdoc --exclude src/tools/rust-analyzer --exclude tests/rustdoc-json --exclude tests/run-make-fulldeps --exclude src/tools/tidy --exclude src/tools/rustdoc-themes --exclude src/rustdoc-json-types --exclude src/librustdoc --exclude src/doc/unstable-book --exclude src/doc/rustdoc --exclude src/doc/rustc --exclude compiler/rustc --exclude library/panic_abort --exclude library/panic_unwind --exclude src/tools/lint-docs --exclude tests/rustdoc-js-std --doc --no-fail-fast --bless"
# Set path for target-poky-linux-gcc, RUST_TARGET_PATH and hosttools.
cmd = " export PATH=%s/recipe-sysroot-native/usr/bin:$PATH;" % rustlibpath
cmd = cmd + " export TARGET_VENDOR=\"-poky\";"
cmd = cmd + " export PATH=%s/recipe-sysroot-native/usr/bin/%s:%s/hosttools:$PATH;" % (rustlibpath, tcpath, tmpdir)
cmd = cmd + " export RUST_TARGET_PATH=%s/rust-targets;" % rustlibpath
# Trigger testing.
cmd = cmd + " export TEST_DEVICE_ADDR=\"%s:12345\";" % qemu.ip
cmd = cmd + " cd %s; python3 src/bootstrap/bootstrap.py test %s --target %s > summary.txt 2>&1;" % (builddir, testargs, targetsys)
runCmd(cmd)
ptestsuite = "rust"
self.ptest_section(ptestsuite, logfile = builddir + "/summary.txt")
filename = builddir + "/summary.txt"
test_results = parse_results(filename)
for test, result in test_results:
self.ptest_result(ptestsuite, test, result)
@OETestTag("toolchain-system")
@OETestTag("runqemu")
class RustSelfTestBase(RustSelfTestSystemEmulated):
def test_check(self):
self.test_rust()

File diff suppressed because it is too large Load Diff

View File

@@ -6,6 +6,7 @@ SRC_URI += "https://static.rust-lang.org/dist/rustc-${RUST_VERSION}-src.tar.xz;n
file://0001-Do-not-use-LFS64-on-linux-with-musl.patch;patchdir=${RUSTSRC} \
file://zlib-off64_t.patch;patchdir=${RUSTSRC} \
file://0001-musl-Define-SOCK_SEQPACKET-in-common-place.patch;patchdir=${RUSTSRC} \
file://rust-oe-selftest.patch;patchdir=${RUSTSRC} \
"
SRC_URI[rust.sha256sum] = "bb8e9c564566b2d3228d95de9063a9254182446a161353f1d843bfbaf5c34639"

View File

@@ -66,6 +66,7 @@ do_rust_setup_snapshot () {
fi
}
addtask rust_setup_snapshot after do_unpack before do_configure
addtask do_test_compile after do_configure do_rust_gen_targets
do_rust_setup_snapshot[dirs] += "${WORKDIR}/rust-snapshot"
do_rust_setup_snapshot[vardepsexclude] += "UNINATIVE_LOADER"
@@ -223,6 +224,11 @@ FILES:${PN}-dev = ""
do_compile () {
}
do_test_compile[dirs] = "${B}"
do_test_compile () {
rust_runx build src/tools/remote-test-server --target "${RUST_TARGET_SYS}"
}
ALLOW_EMPTY:${PN} = "1"
PACKAGES =+ "${PN}-tools-clippy ${PN}-tools-rustfmt"