Skip to contentSkip to conversation

Add gnu testsuite execution for OEQA

PATCH Superseded Nathan Rossi 2 participants 14 messages Aug 28, 2019

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Add gnu testsuite execution for OEQA

This series adds support to execute the gnu test suites for binutils, gcc and glibc. With the intention for enabling automated test running of these test suites within the OEQA framework such that they can be executed by the Yocto Autobuilder.

The test suites covered need significant resources or build artifacts such that running them on the target is undesirable which rules out the use of ptest. Because of this the test suites can be run on the build host and call out to the target for execution (via ssh or using qemu usermode).

The following implementation adds a do_check task to binutils-cross, gcc-cross and gcc-runtime in order to execute the test suite on the build host. For glibc, a second recipe is created which includes the base glibc recipe. The reason for this is due to the libgcc -> glibc -> libgcc-initial dependency chain and the requirements of the test suite to have libgcc for compilation and execution testing.

Target execution is another important issue specifically since target execution is slow to extremely slow depending on the physical or emulated target performance. In order to provide faster execution performance qemu linux-user is implemented alongside qemu system emulation (via ssh+nfs). In initial testing qemu linux user vs qemu system emulation provided performance gains of between 10x to 60x whilst initially having small pass/fail differences. Further work as covered in this series reduces the pass/fail differences for gcc/gcc-runtime close to 0, which can be further reduced by marking known failures with test result filtering.

However glibc is more strict with its expectations of CPU implementation as well as syscall behaviour. Additionally glibc expects to be able to execute OS tools such as 'sh' and 'echo' of which is not easy to provide in the recipe-sysroot (bindir is not populated into the sysroot). As such correct test results for glibc rely on execution with qemu system emulation or on a physical target. This series however still includes qemu user execution for glibc which can be useful (especially on slow targets) assuming the known failing tests are excluded.

           | binutils   | gas        | gold      | ld        | libiberty
arm        |    0/  201 |    0/  862 |   0/   26 |   1/ 1587 |   0/   28
arm64      |    0/  200 |    0/  442 |   0/    9 |   0/ 1591 |   0/   28
mips       |    0/  224 |    0/ 7214 |   1/    5 |  21/ 1786 |   0/   28
ppc        |    0/  197 |    1/  264 |   0/    5 |   0/ 1492 |   0/   28
x86-64     |    0/  243 |    0/ 1185 |   0/   11 |   0/ 2085 |   0/   28
           | gcc        | g++        | libatomic | libgomp   | libitm    | libstdc++-v3
arm        |  31/121900 |   1/127963 |   0/   49 |   0/ 2519 |   0/   46 |     19/12814
arm64      |  32/129632 |   0/128539 |   0/   54 |   0/ 2519 |   0/   46 |      1/12813
mips       | 138/132198 |  20/127706 |   0/   49 |   2/ 2519 |           |     24/12810
ppc        | 356/119730 |  19/128635 |   0/   49 |   2/ 2519 |   0/   46 |     33/13020
x86-64     |  44/135082 |   0/131493 |   0/   54 |   0/ 2526 |   0/   46 |      6/13037
x86-64-kvm |  29/135322 |   0/131493 |   0/   54 |   1/ 2526 |  18/   46 |     49/13034
           | glibc
arm        |   65/ 5240
arm64      |   76/ 5994
mips       |   79/ 5199
ppc        | 1223/ 5254
x86-64     | 1457/ 6101
x86-64-kvm |   47/ 6092

This series also introduces some OEQA test cases which cover running the test suites. The test cases are split into binutils, gcc and glibc. Individual test cases provide execution of the sub-suites of tests within each target. For example binutils has binutils, gas, gold, ld and libiberty suites which can each be executed independently.

The test cases populate the individual test suite test cases into the testresults so that resulttool can analyse them. Filtering of the failed test cases where expected failures occur is not included in this series.

The OEQA test cases implement execution on qemu linux user by default. Subclasses implement qemu system emulation setup and configuration for running the tests.
---

Nathan Rossi (11):
binutils: Add do_check task for executing binutils test suite
gcc-cross: Add do_check task for executing gcc test suite
gcc-runtime: Add do_check task for executing gcc-runtime test suites gcc-common.inc: Process staging fixme with correct target/native
sysroot
glibc-testsuite: Create a recipe to implement glibc test suite
binutils: Fix mips patch which changes default emulation oeqa/selftest/binutils: Create selftest case for binutils test suite oeqa/selftest/gcc: Create selftest case for gcc test suite oeqa/utils/nfs: Add unfs_server function to setup a userspace NFS
server
oeqa/selftest/glibc: Create selftest case for glibc test suite scripts/lib/resulttool/report.py: Add more result types

 meta/lib/oeqa/selftest/cases/binutils.py      |  95 ++++++++++++++++
 meta/lib/oeqa/selftest/cases/gcc.py           | 107 ++++++++++++++++++
 meta/lib/oeqa/selftest/cases/glibc.py         |  91 +++++++++++++++
 meta/lib/oeqa/utils/network.py                |   4 +-
 meta/lib/oeqa/utils/nfs.py                    |  39 +++++++
 .../glibc/glibc-testsuite_2.30.bb             |  51 +++++++++
 .../glibc/glibc/check-test-wrapper            |  71 ++++++++++++
 .../binutils/binutils-cross.inc               |  28 +++++
 ...e-default-emulation-for-mips64-linux.patch |   9 +-
 meta/recipes-devtools/gcc/gcc-common.inc      |   2 +-
 meta/recipes-devtools/gcc/gcc-cross.inc       |  41 +++++++
 meta/recipes-devtools/gcc/gcc-runtime.inc     |  37 ++++++
 meta/recipes-devtools/gcc/gcc-testsuite.inc   | 106 +++++++++++++++++
 scripts/lib/resulttool/report.py              |   6 +-
 14 files changed, 675 insertions(+), 12 deletions(-)
 create mode 100644 meta/lib/oeqa/selftest/cases/binutils.py
 create mode 100644 meta/lib/oeqa/selftest/cases/gcc.py
 create mode 100644 meta/lib/oeqa/selftest/cases/glibc.py
 create mode 100644 meta/lib/oeqa/utils/nfs.py
 create mode 100644 meta/recipes-core/glibc/glibc-testsuite_2.30.bb
 create mode 100644 meta/recipes-core/glibc/glibc/check-test-wrapper
 create mode 100644 meta/recipes-devtools/gcc/gcc-testsuite.inc

---
2.23.0.rc1

#1 lore raw

PATCH 1/11 binutils: Add do_check task for executing binutils test suite

Create the do_check task to the binutils-cross include. This task can be used to execute the binutils test suite for the cross target binutils. By default this executes all the check targets of the binutils Makefile, this can however be changed by setting MAKE_CHECK_TARGETS to the desired test suite target (e.g. check-gas).

The binutils test suites do not require any target execution, as such the check target can be run without QEMU or a target device. However since the binutils tests do rely on a C compiler there is dependence on both gcc and libc in order to run the tests.

---
 meta/recipes-devtools/binutils/binutils-cross.inc | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)
meta/recipes-devtools/binutils/binutils-cross.inc +28 -0
index 02ec891606..76eb453f0e 100644
@@ -36,3 +36,31 @@ do_install () {
 	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir}64 || :
 	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${prefix} || :
 }
+
+EXTRA_OEMAKE_prepend_task-check = "${PARALLEL_MAKE} "
+MAKE_CHECK_TARGETS ??= "check-binutils check-gas check-gold check-ld check-libiberty"
+
+python () {
+    # crosssdk deps have different virtual targets
+    if bb.data.inherits_class('crosssdk', d):
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}gcc-crosssdk:do_populate_sysroot")
+        d.appendVarFlag("do_check", "depends", " virtual/nativesdk-${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+    else:
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}gcc:do_populate_sysroot")
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+}
+
+do_check[depends] += "dejagnu-native:do_populate_sysroot expect-native:do_populate_sysroot"
+do_check[depends] += "virtual/libc:do_populate_sysroot"
+do_check[dirs] = "${B}"
+do_check[nostamp] = "1"
+do_check() {
+    # need to inject CC and CXX as the target CC and CXX with sysroot
+    oe_runmake -i ${MAKE_CHECK_TARGETS} \
+        RUNTESTFLAGS=" \
+            CC='${TARGET_PREFIX}gcc --sysroot=${STAGING_DIR_TARGET} ${TUNE_CCARGS}' \
+            CXX='${TARGET_PREFIX}g++ --sysroot=${STAGING_DIR_TARGET} ${TUNE_CCARGS}' \
+            "
+}
+addtask check after do_compile
+

---
2.23.0.rc1

#2 lore raw

Re: [PATCH 1/11] binutils: Add do_check task for executing binutils test suite

Quoted 27 lines · Nathan Rossi

Create the do_check task to the binutils-cross include. This task can be used to execute the binutils test suite for the cross target binutils. By default this executes all the check targets of the binutils Makefile, this can however be changed by setting MAKE_CHECK_TARGETS to the desired test suite target (e.g. check-gas).

The binutils test suites do not require any target execution, as such the check target can be run without QEMU or a target device. However since the binutils tests do rely on a C compiler there is dependence on both gcc and libc in order to run the tests.

---
 meta/recipes-devtools/binutils/binutils-cross.inc | 28 +++++++++++++++++++++++
 1 file changed, 28 insertions(+)
meta/recipes-devtools/binutils/binutils-cross.inc +3 -0
index 02ec891606..76eb453f0e 100644
@@ -36,3 +36,31 @@ do_install () {
 	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${libdir}64 || :
 	rmdir ${D}${STAGING_DIR_NATIVE}${prefix_native}/${prefix} || :
 }
+
+EXTRA_OEMAKE_prepend_task-check = "${PARALLEL_MAKE} "
+MAKE_CHECK_TARGETS ??= "check-binutils check-gas check-gold check-ld check-libiberty"

meta/recipes-devtools/binutils/binutils-cross.inc do_install () { · line 51

Quoted 10 lines
meta/recipes-devtools/binutils/binutils-cross.inc +10 -0
+
+python () {
+    # crosssdk deps have different virtual targets
+    if bb.data.inherits_class('crosssdk', d):
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}gcc-crosssdk:do_populate_sysroot")
+        d.appendVarFlag("do_check", "depends", " virtual/nativesdk-${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+    else:
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}gcc:do_populate_sysroot")
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+}

I'm torn here on whether we should do:

do_check[depends] += "${BINUTILS_TARGETDEPS}"
BINUTILS_TARGETDEPS = "virtual/${TARGET_PREFIX}gcc:do_populate_sysroot virtual/${TARGET_PREFIX}compilerlibs:do_populate_sysroot" BINUTILS_TARGETDEPS_class-crosssdk = "virtual/${TARGET_PREFIX}gcc-crosssdk:do_populate_sysroot virtual/nativesdk-${TARGET_PREFIX}compilerlibs:do_populate_sysroot"

instead of the above.

Cheers,

Richard

Quoted 17 lines
meta/recipes-devtools/binutils/binutils-cross.inc +14 -1
+do_check[depends] += "dejagnu-native:do_populate_sysroot expect-native:do_populate_sysroot"
+do_check[depends] += "virtual/libc:do_populate_sysroot"
+do_check[dirs] = "${B}"
+do_check[nostamp] = "1"
+do_check() {
+    # need to inject CC and CXX as the target CC and CXX with sysroot
+    oe_runmake -i ${MAKE_CHECK_TARGETS} \
+        RUNTESTFLAGS=" \
+            CC='${TARGET_PREFIX}gcc --sysroot=${STAGING_DIR_TARGET} ${TUNE_CCARGS}' \
+            CXX='${TARGET_PREFIX}g++ --sysroot=${STAGING_DIR_TARGET} ${TUNE_CCARGS}' \
+            "
+}
+addtask check after do_compile
+
---

2.23.0.rc1

#3 lore raw

Re: [PATCH 1/11] binutils: Add do_check task for executing binutils test suite

In reply to Nathan Rossi
Quoted 10 lines · Nathan Rossi

Create the do_check task to the binutils-cross include. This task can be
used to execute the binutils test suite for the cross target binutils.
By default this executes all the check targets of the binutils Makefile,
this can however be changed by setting MAKE_CHECK_TARGETS to the desired
test suite target (e.g. check-gas).

Quoted 7 lines

The binutils test suites do not require any target execution, as such the check target can be run without QEMU or a target device. However since the binutils tests do rely on a C compiler there is dependence on
both gcc and libc in order to run the tests.

Looking at this a bit further we have a problem with gcc-cross and binutils-cross.

The trouble is we extracted all "target" dependencies away from the cross recipes. This means we build *-cross once per target arch but the runtime pieces are build once per target tune.

The tests are very much target tune specific so shouldn't be in the cross recipes.

This is going to cause worlds of pain when we switch between machines that use the same arch but different tunes and the sysroot has files from a previous different tune.

I suspect this will manifest itself should we run the signature checks but there real underlying problem here people will run into that we'll have to solve before this can merge.

There is a secondary issue later in the series with adding the test results to "selftest".

On the autobuilder we run "selftest" once and assume its machine independent. These results clearly aren't. This gives problems for both running the tests and processing the results.

Equally, "cross" toolchain tests aren't really "runtime" but are machine/target specific. FWIW, injecting the test results the way you are doing is good and the right thing to do but I think we may need a different class of test, or we inject them as a special case of runtime test, or runtime ptest (a cross runtime ptest result?).

I'm happy to try and help figure out how to address some of this if I can help somehow. I am conscious the release deadlines are pressing too :(.

Cheers,

Richard

#4 lore raw

PATCH 2/11 gcc-cross: Add do_check task for executing gcc test suite

In reply to Nathan Rossi

Add a do_check task and supporting configuration to implement execution of the gcc compiler test suite. The test suite requires execution of compiled programs.

The implementation provided allows for execution testing against a host via SSH or within the local build environment using qemu linux-user execution. The selection of execution is done via the BUILD_TEST_TARGET variable, and configuration of the remote host is done with the BUILD_TEST_HOST, BUILD_TEST_HOST_USER and BUILD_TEST_HOST_PORT variables.

By default the do_check task will execute all check targets, this can be changed by setting MAKE_CHECK_TARGETS to the desired test suite target (e.g. check-gcc or check-g++).

---
 meta/recipes-devtools/gcc/gcc-cross.inc     |  41 +++++++++++
 meta/recipes-devtools/gcc/gcc-testsuite.inc | 106 ++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+)
 create mode 100644 meta/recipes-devtools/gcc/gcc-testsuite.inc
meta/recipes-devtools/gcc/gcc-cross.inc +41 -0
index 6222c2e8c9..f9534340d2 100644
@@ -221,3 +221,44 @@ python do_gcc_stash_builddir_setscene () {
     sstate_setscene(d)
 }
 addtask do_gcc_stash_builddir_setscene
+
+require gcc-testsuite.inc
+
+check_prepare_sysroot () {
+    if [ ! -s ${RECIPE_SYSROOT}${target_includedir}/limits.h ]; then
+        # this file was created by the configure task, but is replaced by the
+        # libc version when populating the sysroot for the do_check task
+        rm ${RECIPE_SYSROOT}${target_includedir}/limits.h
+    fi
+}
+
+EXTRA_OEMAKE_prepend_task-check = "${PARALLEL_MAKE} "
+
+MAKE_CHECK_TARGETS ??= "check-gcc check-g++ check-lto"
+
+python () {
+    # crosssdk deps have different virtual targets
+    if bb.data.inherits_class('crosssdk', d):
+        d.appendVarFlag("do_check", "depends", " virtual/nativesdk-${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+    else:
+        d.appendVarFlag("do_check", "depends", " virtual/${TARGET_PREFIX}compilerlibs:do_populate_sysroot")
+}
+
+# specific host and target dependencies required for test suite running
+do_check[depends] += "dejagnu-native:do_populate_sysroot expect-native:do_populate_sysroot"
+do_check[depends] += "virtual/libc:do_populate_sysroot"
+# only depend on qemu if targeting linux user execution
+do_check[depends] += "${@'qemu-native:do_populate_sysroot' if "user" in d.getVar('BUILD_TEST_TARGET') else ''}"
+# check_prepare_sysroot is before extend in order to perform the limits.h removal
+do_check[prefuncs] += "check_prepare_sysroot"
+do_check[prefuncs] += "extend_recipe_sysroot"
+do_check[prefuncs] += "check_prepare"
+do_check[dirs] = "${WORKDIR}/dejagnu ${B}"
+do_check[nostamp] = "1"
+do_check() {
+    export DEJAGNU="${WORKDIR}/dejagnu/site.exp"
+
+    oe_runmake -i -C ${B}/gcc ${MAKE_CHECK_TARGETS} RUNTESTFLAGS="${MAKE_CHECK_BOARDARGS}"
+}
+addtask check after do_compile do_populate_sysroot
+
meta/recipes-devtools/gcc/gcc-testsuite.inc new file +106 -0

106 lines not on this page · raw message

---
2.23.0.rc1

#5 lore raw

PATCH 3/11 gcc-runtime: Add do_check task for executing gcc-runtime test suites

In reply to Nathan Rossi

Add a do_check task to implement execution of the gcc-runtime component test suites. The component test suites require execution of compiled programs on the target, this recipe reuses the same setup as gcc-cross for setup of the target (either as ssh or qemu linux-user).

---
 meta/recipes-devtools/gcc/gcc-runtime.inc | 37 +++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)
meta/recipes-devtools/gcc/gcc-runtime.inc +37 -0
index 22c1d78dd1..ce0b5e482d 100644
@@ -277,3 +277,40 @@ FILES_libitm-dev = "\
 SUMMARY_libitm-dev = "GNU transactional memory support library - development files"
 FILES_libitm-staticdev = "${libdir}/libitm.a"
 SUMMARY_libitm-staticdev = "GNU transactional memory support library - static development files"
+
+require gcc-testsuite.inc
+
+EXTRA_OEMAKE_prepend_task-check = "${PARALLEL_MAKE} "
+
+MAKE_CHECK_TARGETS ??= "${@" ".join("check-target-" + i for i in d.getVar("RUNTIMETARGET").split())}"
+MAKE_CHECK_IGNORE ??= "prettyprinters.exp xmethods.exp"
+MAKE_CHECK_RUNTESTFLAGS ??= "${MAKE_CHECK_BOARDARGS} --ignore '${MAKE_CHECK_IGNORE}'"
+
+# specific host and target dependencies required for test suite running
+do_check[depends] += "dejagnu-native:do_populate_sysroot expect-native:do_populate_sysroot"
+do_check[depends] += "virtual/libc:do_populate_sysroot"
+# only depend on qemu if targeting linux user execution
+do_check[depends] += "${@'qemu-native:do_populate_sysroot' if "user" in d.getVar('BUILD_TEST_TARGET') else ''}"
+# extend the recipe sysroot to include the built libraries (for qemu usermode)
+do_check[prefuncs] += "extend_recipe_sysroot"
+do_check[prefuncs] += "check_prepare"
+do_check[dirs] = "${WORKDIR}/dejagnu ${B}"
+do_check[nostamp] = "1"
+do_check() {
+    export DEJAGNU="${WORKDIR}/dejagnu/site.exp"
+
+    # HACK: this works around the configure setting CXX with -nostd* args
+    sed -i 's/-nostdinc++ -nostdlib++//g' $(find ${B} -name testsuite_flags | head -1)
+
+    if [ "${BUILD_TEST_TARGET}" = "user" ]; then
+        # qemu user has issues allocating large amounts of memory
+        export G_SLICE=always-malloc
+        # no test should need more that 10G of memory, this prevents tests like pthread7-rope from leaking memory
+        ulimit -m 4194304
+        ulimit -v 10485760
+    fi
+
+    oe_runmake -i ${MAKE_CHECK_TARGETS} RUNTESTFLAGS="${MAKE_CHECK_RUNTESTFLAGS}"
+}
+addtask check after do_compile do_populate_sysroot
+

---
2.23.0.rc1

#6 lore raw

PATCH 4/11 gcc-common.inc: Process staging fixme with correct target/native sysroot

In reply to Nathan Rossi

Correct the 'staging_processfixme' call so that target sysroot and native sysroot paths are corrected when extracting the stashed build directory. This is required for 'make check' to work correctly due paths used in configuration and scripts which point at the native sysroot.

---
 meta/recipes-devtools/gcc/gcc-common.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
meta/recipes-devtools/gcc/gcc-common.inc +1 -1
index 96334e54b4..a8f4b60c32 100644
@@ -17,7 +17,7 @@ python extract_stashed_builddir () {
     src = d.expand("${COMPONENTS_DIR}/${BUILD_ARCH}/gcc-stashed-builddir-${TARGET_SYS}")
     dest = d.getVar("B")
     oe.path.copyhardlinktree(src, dest)
-    staging_processfixme([src + "/fixmepath"], dest, dest, dest, d)
+    staging_processfixme([src + "/fixmepath"], dest, d.getVar("RECIPE_SYSROOT"), d.getVar("RECIPE_SYSROOT_NATIVE"), d)
 }
 
 def get_gcc_float_setting(bb, d):

---
2.23.0.rc1

#7 lore raw

PATCH 5/11 glibc-testsuite: Create a recipe to implement glibc test suite

In reply to Nathan Rossi

A recipe needs to be created for the test suite due to the dependency chain between libgcc -> glibc -> libgcc-initial, and the requirements of the test suite to have libgcc for compilation and execution.

The glibc test suite does not use dejagnu like the gcc test suites do. Instead a test wrapper script is used along with the assumed dependency of having the same filesystem available on build host and target. For qemu linux-user the same filesystem is inherently available, for remote targets NFS is used. Separate test wrapper scripts are created for qemu linux-user or ssh targets, with the same BUILD_TEST_* variables used for configuration.

---
 meta/recipes-core/glibc/glibc-testsuite_2.30.bb  | 51 +++++++++++++++++
 meta/recipes-core/glibc/glibc/check-test-wrapper | 71 ++++++++++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 meta/recipes-core/glibc/glibc-testsuite_2.30.bb
 create mode 100644 meta/recipes-core/glibc/glibc/check-test-wrapper
meta/recipes-core/glibc/glibc-testsuite_2.30.bb new file +51 -0
new file mode 100644
index 0000000000..665619377d
@@ -0,0 +1,51 @@
+require glibc_${PV}.bb
+
+# handle PN differences
+FILESEXTRAPATHS_prepend := "${THISDIR}/glibc:"
+
+# strip provides
+PROVIDES = ""
+# setup depends
+INHIBIT_DEFAULT_DEPS = ""
+
+DEPENDS += "glibc-locale libgcc gcc-runtime"
+
+# remove the initial depends
+DEPENDS_remove = "libgcc-initial"
+
+inherit qemu
+
+SRC_URI += "file://check-test-wrapper"
+
+DEPENDS += "${@'qemu-native' if d.getVar('BUILD_TEST_TARGET') == 'user' else ''}"
+
+BUILD_TEST_TARGET ??= "user"
+BUILD_TEST_HOST ??= "localhost"
+BUILD_TEST_HOST_USER ??= "root"
+BUILD_TEST_HOST_PORT ??= "2222"
+
+do_check[dirs] += "${B}"
+do_check[nostamp] = "1"
+do_check () {
+    chmod 0755 ${WORKDIR}/check-test-wrapper
+
+    # clean out previous test results
+    oe_runmake tests-clean
+    # makefiles don't clean entirely (and also sometimes fails due to too many args)
+    find ${B} -type f -name "*.out" -delete
+    find ${B} -type f -name "*.test-result" -delete
+    find ${B}/catgets -name "*.cat" -delete
+    find ${B}/conform -name "symlist-*" -delete
+    [ ! -e ${B}/timezone/testdata ] || rm -rf ${B}/timezone/testdata
+
+    oe_runmake -i \
+        QEMU_SYSROOT="${RECIPE_SYSROOT}" \
+        QEMU_OPTIONS="${@qemu_target_binary(d)} ${QEMU_OPTIONS}" \
+        SSH_HOST="${BUILD_TEST_HOST}" \
+        SSH_HOST_USER="${BUILD_TEST_HOST_USER}" \
+        SSH_HOST_PORT="${BUILD_TEST_HOST_PORT}" \
+        test-wrapper="${WORKDIR}/check-test-wrapper ${BUILD_TEST_TARGET}" \
+        check
+}
+addtask do_check after do_compile
+
meta/recipes-core/glibc/glibc/check-test-wrapper new file +71 -0

71 lines not on this page · raw message

---
2.23.0.rc1

#8 lore raw

PATCH 6/11 binutils: Fix mips patch which changes default emulation

In reply to Nathan Rossi

The patch incorrectly removes 'mips_elf32_ntrad_le_vec' from the 'targ_selvecs' replacing it with duplicate entries for 'mips_elf32_ntrad_be_vec'. Correct this so that the default binutils can still handle 'mips_elf32_ntrad_le_vec' binaries.

---
 .../0010-Change-default-emulation-for-mips64-linux.patch         | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)
meta/recipes-devtools/binutils/binutils/0010-Change-default-emulation-for-mips64-linux.patch +3 -6
index ba5e4c2ce5..5f4ac72f48 100644
@@ -1,4 +1,4 @@
-From d540e95d05cd7c4b8924ac7b257c14ae0105d0ab Mon Sep 17 00:00:00 2001
+From 958a49749b772660d3bafb80748829cba6bed065 Mon Sep 17 00:00:00 2001
 From: Khem Raj <[email protected]>
 Date: Mon, 2 Mar 2015 01:44:14 +0000
 Subject: [PATCH 10/15] Change default emulation for mips64*-*-linux
@@ -14,7 +14,7 @@ Signed-off-by: Khem Raj <[email protected]>
  2 files changed, 8 insertions(+), 8 deletions(-)
 
 diff --git a/bfd/config.bfd b/bfd/config.bfd
-index 0e1ddb659c..cc65547588 100644
+index 0e1ddb659c..d4f50f0a8d 100644
 --- a/bfd/config.bfd
 +++ b/bfd/config.bfd
 @@ -919,12 +919,12 @@ case "${targ}" in
@@ -30,7 +30,7 @@ index 0e1ddb659c..cc65547588 100644
 -    targ_defvec=mips_elf32_ntrad_be_vec
 -    targ_selvecs="mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_be_vec mips_elf64_trad_le_vec"
 +    targ_defvec=mips_elf64_trad_be_vec
-+    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_be_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
++    targ_selvecs="mips_elf32_ntrad_be_vec mips_elf32_ntrad_le_vec mips_elf32_trad_be_vec mips_elf32_trad_le_vec mips_elf64_trad_le_vec"
      ;;
    mips*el-*-linux*)
      targ_defvec=mips_elf32_trad_le_vec
@@ -54,6 +54,3 @@ index beba17ef51..917be6f8eb 100644
  			targ_extra_libpath=$targ_extra_emuls ;;
  mips*el-*-linux-*)	targ_emul=elf32ltsmip
  			targ_extra_emuls="elf32btsmip elf32ltsmipn32 elf64ltsmip elf32btsmipn32 elf64btsmip"
--- 
-2.20.1
-

---
2.23.0.rc1

#9 lore raw

PATCH 7/11 oeqa/selftest/binutils: Create selftest case for binutils test suite

In reply to Nathan Rossi

Create a oeqa selftest test case to execute the binutils test suites and report the results. The results are populated into the extraresults variable of the test case which are written to testresults.json for resulttool to analyse.

---
 meta/lib/oeqa/selftest/cases/binutils.py | 95 ++++++++++++++++++++++++++++++++
 1 file changed, 95 insertions(+)
 create mode 100644 meta/lib/oeqa/selftest/cases/binutils.py
meta/lib/oeqa/selftest/cases/binutils.py new file +95 -0
new file mode 100644
index 0000000000..5cb7e106ac
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: MIT
+import os
+import sys
+import re
+import logging
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars
+
+def parse_values(content, gold = False):
+    suffix = ": " if not gold else " "
+    for i in content:
+        for v in ["PASS", "FAIL", "XPASS", "XFAIL", "UNRESOLVED", "UNSUPPORTED", "UNTESTED", "ERROR", "WARNING"]:
+            if i.startswith(v + suffix):
+                name = i[len(v) + len(suffix):].strip()
+                if v == "FAIL" and gold: # clean off exit status on gold
+                    name = name.split(" (exit status:")[0]
+                yield name, v
+                break
+
+class BinutilsCrossSelfTest(OESelftestTestCase):
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+        if not hasattr(cls.tc, "extraresults"):
+            cls.tc.extraresults = {}
+
+    def test_binutils(self):
+        self.run_binutils("binutils")
+
+    def test_gas(self):
+        self.run_binutils("gas")
+
+    def test_ld(self):
+        self.run_binutils("ld")
+
+    def test_gold(self):
+        self.run_binutils("gold")
+
+    def test_libiberty(self):
+        self.run_binutils("libiberty")
+
+    def run_binutils(self, suite):
+        features = []
+        features.append('MAKE_CHECK_TARGETS = "check-{0}"'.format(suite))
+        self.write_config("\n".join(features))
+
+        tune_arch = get_bb_var("TUNE_ARCH")
+        recipe = "binutils-cross-{0}".format(tune_arch)
+        bb_vars = get_bb_vars(["B", "TARGET_SYS", "T"], recipe)
+        builddir, target_sys, tdir = bb_vars["B"], bb_vars["TARGET_SYS"], bb_vars["T"]
+
+        bitbake("{0} -c check".format(recipe))
+
+        failed = 0
+        def add_result(test, result):
+            nonlocal failed
+            self.tc.extraresults["binutils.{}.{}".format(suite, test)] = {"status" : result}
+            if result == "FAIL":
+                self.logger.info("failed: '{}'".format(test))
+                failed += 1
+
+        if suite in ["binutils", "gas", "ld"]:
+            sumspath = os.path.join(builddir, suite, "{0}.sum".format(suite))
+            if not os.path.exists(sumspath):
+                sumspath = os.path.join(builddir, suite, "testsuite", "{0}.sum".format(suite))
+            with open(sumspath, "r") as f:
+                for test, result in parse_values(f):
+                    add_result(test, result)
+        elif suite in ["gold"]:
+            # gold tests are not dejagnu, so no sums file
+            logspath = os.path.join(builddir, suite, "testsuite")
+            if os.path.exists(logspath):
+                for t in os.listdir(logspath):
+                    if not t.endswith(".log") or t == "test-suite.log":
+                        continue
+                    with open(os.path.join(logspath, t), "r") as f:
+                        for test, result in parse_values(f, gold = True):
+                            add_result(test, result)
+            else:
+                self.skipTest("Target does not use {0}".format(suite))
+        elif suite in ["libiberty"]:
+            # libiberty tests are not dejagnu, no sums or log files
+            logpath = os.path.join(tdir, "log.do_check")
+            if os.path.exists(logpath):
+                with open(logpath, "r") as f:
+                    logdata = f.read()
+                m = re.search(r"entering directory\s+'[^\r\n]+?libiberty/testsuite'.*?$(.*?)" +
+                    "^[^\r\n]+?leaving directory\s+'[^\r\n]+?libiberty/testsuite'.*?$",
+                    logdata, re.DOTALL | re.MULTILINE | re.IGNORECASE)
+                if m is not None:
+                    for test, result in parse_values(m.group(1).splitlines()):
+                        add_result(test, result)
+
+        self.assertEqual(failed, 0)
+

---
2.23.0.rc1

#10 lore raw

PATCH 8/11 oeqa/selftest/gcc: Create selftest case for gcc test suite

In reply to Nathan Rossi

Create a oeqa selftest test case to execute the gcc test suites and report the results. The results are populated into the extraresults variable of the test case which are written to testresults.json for resulttool to analyse.

An additional subclass is created to separate the execution with qemu linux-user and qemu system. The GccSelfTestSystemEmulated test case handles setup of the target image as well as execution with runqemu.

---
 meta/lib/oeqa/selftest/cases/gcc.py | 107 ++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 meta/lib/oeqa/selftest/cases/gcc.py
meta/lib/oeqa/selftest/cases/gcc.py new file +107 -0
new file mode 100644
index 0000000000..c36637d066
@@ -0,0 +1,107 @@
+# SPDX-License-Identifier: MIT
+import os
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars, runqemu, Command
+
+def parse_values(content):
+    for i in content:
+        for v in ["PASS", "FAIL", "XPASS", "XFAIL", "UNRESOLVED", "UNSUPPORTED", "UNTESTED", "ERROR", "WARNING"]:
+            if i.startswith(v + ": "):
+                yield i[len(v) + 2:].strip(), v
+                break
+
+class GccSelfTest(OESelftestTestCase):
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+        if not hasattr(cls.tc, "extraresults"):
+            cls.tc.extraresults = {}
+
+    def gcc_runtime_check_skip(self, suite):
+        targets = get_bb_var("RUNTIMETARGET", "gcc-runtime").split()
+        if suite not in targets:
+            self.skipTest("Target does not use {0}".format(suite))
+
+    def test_cross_gcc(self):
+        self.gcc_cross_run_check("gcc")
+
+    def test_cross_gxx(self):
+        self.gcc_cross_run_check("g++")
+
+    def test_gcc_runtime_libatomic(self):
+        self.gcc_runtime_run_check("libatomic")
+
+    def test_gcc_runtime_libgomp(self):
+        self.gcc_runtime_run_check("libgomp")
+
+    def test_gcc_runtime_libstdcxx(self):
+        self.gcc_runtime_run_check("libstdc++-v3")
+
+    def test_gcc_runtime_libssp(self):
+        self.gcc_runtime_check_skip("libssp")
+        self.gcc_runtime_run_check("libssp")
+
+    def test_gcc_runtime_libitm(self):
+        self.gcc_runtime_check_skip("libitm")
+        self.gcc_runtime_run_check("libitm")
+
+    def gcc_cross_run_check(self, suite):
+        return self.gcc_run_check("gcc-cross-{0}".format(get_bb_var("TUNE_ARCH")), suite)
+
+    def gcc_runtime_run_check(self, suite):
+        return self.gcc_run_check("gcc-runtime", suite, target_prefix = "check-target-")
+
+    def gcc_run_check(self, recipe, suite, target_prefix = "check-", ssh = None):
+        target = target_prefix + suite.replace("gcc", "gcc").replace("g++", "c++")
+
+        # configure ssh target
+        features = []
+        features.append('MAKE_CHECK_TARGETS = "{0}"'.format(target))
+        if ssh is not None:
+            features.append('BUILD_TEST_TARGET = "ssh"')
+            features.append('BUILD_TEST_HOST = "{0}"'.format(ssh))
+            features.append('BUILD_TEST_HOST_USER = "root"')
+            features.append('BUILD_TEST_HOST_PORT = "22"')
+        self.write_config("\n".join(features))
+
+        bitbake("{0} -c check".format(recipe))
+
+        bb_vars = get_bb_vars(["TUNE_ARCH", "B", "TARGET_SYS"], recipe)
+        tune_arch, builddir, target_sys = bb_vars["TUNE_ARCH"], bb_vars["B"], bb_vars["TARGET_SYS"]
+
+        sumspath = os.path.join(builddir, "gcc", "testsuite", suite, "{0}.sum".format(suite))
+        if not os.path.exists(sumspath): # check in target dirs
+            sumspath = os.path.join(builddir, target_sys, suite, "testsuite", "{0}.sum".format(suite))
+        if not os.path.exists(sumspath): # handle libstdc++-v3 -> libstdc++
+            sumspath = os.path.join(builddir, target_sys, suite, "testsuite", "{0}.sum".format(suite.split("-")[0]))
+
+        failed = 0
+        with open(sumspath, "r") as f:
+            for test, result in parse_values(f):
+                self.tc.extraresults["{}.{}.{}".format(type(self).__name__, suite, test)] = {"status" : result}
+                if result == "FAIL":
+                    self.logger.info("failed: '{}'".format(test))
+                    failed += 1
+        self.assertEqual(failed, 0)
+
+class GccSelfTestSystemEmulated(GccSelfTest):
+    default_installed_packages = ["libgcc", "libstdc++", "libatomic", "libgomp"]
+
+    def gcc_run_check(self, *args, **kwargs):
+        tune_arch = get_bb_var("TUNE_ARCH")
+
+        # build core-image-minimal with required packages
+        features = []
+        features.append('IMAGE_FEATURES += "ssh-server-openssh"')
+        features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(self.default_installed_packages)))
+        self.write_config("\n".join(features))
+        bitbake("core-image-minimal")
+
+        # wrap the execution with a qemu instance
+        with runqemu("core-image-minimal", runqemuparams = "nographic") as qemu:
+            # validate that SSH is working
+            status, _ = qemu.run("uname")
+            self.assertEqual(status, 0)
+
+            return super().gcc_run_check(*args, **kwargs, ssh = qemu.ip)
+

---
2.23.0.rc1

#11 lore raw

PATCH 9/11 oeqa/utils/nfs: Add unfs_server function to setup a userspace NFS server

In reply to Nathan Rossi

Add a nfs module into oeqa utils. This module provides unfs_server which allows a test case to build unfs3-native and setup the unfs server on a target directory of the host. This directory is then shared and can be mounted by the host or a target device attached to the host (e.g. qemu via tap or slirp). The nfs server is setup over UDP and automatically assigns user privileged ports. The function provides the UDP ports for the server as part of a returned python contextmanager which handles cleanup of the server process on completion or exception.

Also add a 'udp' arg to get_free_port to get a free UDP port.

Note: unfs3 still requires the host to have rpcbind or portmap running.

---
 meta/lib/oeqa/utils/network.py |  4 ++--
 meta/lib/oeqa/utils/nfs.py     | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 meta/lib/oeqa/utils/nfs.py
meta/lib/oeqa/utils/network.py +2 -2
index 59cbbc4f1b..59d01723a1 100644
@@ -4,8 +4,8 @@
 
 import socket
 
-def get_free_port():
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+def get_free_port(udp = False):
+    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM if not udp else socket.SOCK_DGRAM)
     s.bind(('', 0))
     addr = s.getsockname()
     s.close()
meta/lib/oeqa/utils/nfs.py new file +39 -0
new file mode 100644
index 0000000000..a37686c914
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: MIT
+import os
+import sys
+import tempfile
+import contextlib
+import socket
+from oeqa.utils.commands import bitbake, get_bb_var, Command
+from oeqa.utils.network import get_free_port
+
[email protected]
+def unfs_server(directory, logger = None):
+    unfs_sysroot = get_bb_var("RECIPE_SYSROOT_NATIVE", "unfs3-native")
+    if not os.path.exists(os.path.join(unfs_sysroot, "usr", "bin", "unfsd")):
+        # build native tool
+        bitbake("unfs3-native -c addto_recipe_sysroot")
+
+    exports = None
+    cmd = None
+    try:
+        # create the exports file
+        with tempfile.NamedTemporaryFile(delete = False) as exports:
+            exports.write("{0} (rw,no_root_squash,no_all_squash,insecure)\n".format(directory).encode())
+
+        # find some ports for the server
+        nfsport, mountport = get_free_port(udp = True), get_free_port(udp = True)
+
+        nenv = dict(os.environ)
+        nenv['PATH'] = "{0}/sbin:{0}/usr/sbin:{0}/usr/bin:".format(unfs_sysroot) + nenv.get('PATH', '')
+        cmd = Command(["unfsd", "-d", "-p", "-N", "-e", exports.name, "-n", str(nfsport), "-m", str(mountport)],
+                bg = True, env = nenv, output_log = logger)
+        cmd.run()
+        yield nfsport, mountport
+    finally:
+        if cmd is not None:
+            cmd.stop()
+        if exports is not None:
+            # clean up exports file
+            os.unlink(exports.name)
+

---
2.23.0.rc1

#12 lore raw

PATCH 10/11 oeqa/selftest/glibc: Create selftest case for glibc test suite

In reply to Nathan Rossi

Create a oeqa selftest test case to execute the glibc test suite and report the results. The results are populated into the extraresults variable of the test case which are written to testresults.json for resulttool to analyse.

An additional subclass is created to separate the execution with qemu linux-user and qemu system. The GlibcSelfTestSystemEmulated test case handles setup of the target image, setup of and NFS server as well as execution with runqemu.

---
 meta/lib/oeqa/selftest/cases/glibc.py | 91 +++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)
 create mode 100644 meta/lib/oeqa/selftest/cases/glibc.py
meta/lib/oeqa/selftest/cases/glibc.py new file +91 -0
new file mode 100644
index 0000000000..5252ebb1b5
@@ -0,0 +1,91 @@
+# SPDX-License-Identifier: MIT
+import os
+import contextlib
+from oeqa.selftest.case import OESelftestTestCase
+from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars, runqemu, Command
+from oeqa.utils.nfs import unfs_server
+
+def parse_values(content):
+    for i in content:
+        for v in ["PASS", "FAIL", "XPASS", "XFAIL", "UNRESOLVED", "UNSUPPORTED", "UNTESTED", "ERROR", "WARNING"]:
+            if i.startswith(v + ": "):
+                yield i[len(v) + 2:].strip(), v
+                break
+
+class GlibcSelfTest(OESelftestTestCase):
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass()
+        if not hasattr(cls.tc, "extraresults"):
+            cls.tc.extraresults = {}
+
+    def test_glibc(self):
+        self.glibc_run_check()
+
+    def glibc_run_check(self, ssh = None):
+        # configure ssh target
+        features = []
+        if ssh is not None:
+            features.append('BUILD_TEST_TARGET = "ssh"')
+            features.append('BUILD_TEST_HOST = "{0}"'.format(ssh))
+            features.append('BUILD_TEST_HOST_USER = "root"')
+            features.append('BUILD_TEST_HOST_PORT = "22"')
+            # force single threaded test execution
+            features.append('EGLIBCPARALLELISM_task-check_pn-glibc-testsuite = "PARALLELMFLAGS="-j1""')
+        self.write_config("\n".join(features))
+
+        bitbake("glibc-testsuite -c check")
+
+        builddir = get_bb_var("B", "glibc-testsuite")
+
+        failed = 0
+        with open(os.path.join(builddir, "tests.sum"), "r") as f:
+            for test, result in parse_values(f):
+                self.tc.extraresults["{}.{}".format(type(self).__name__, test)] = {"status" : result}
+                if result == "FAIL":
+                    self.logger.info("failed: '{}'".format(test))
+                    failed += 1
+        self.assertEqual(failed, 0)
+
+class GlibcSelfTestSystemEmulated(GlibcSelfTest):
+    default_installed_packages = [
+        "glibc-charmaps",
+        "libgcc",
+        "libstdc++",
+        "libatomic",
+        "libgomp",
+        "python3",
+        "python3-pexpect",
+        "nfs-utils",
+        ]
+
+    def glibc_run_check(self):
+        with contextlib.ExitStack() as s:
+            # use the base work dir, as the nfs mount, since the recipe directory may not exist
+            tmpdir = get_bb_var("BASE_WORKDIR")
+            nfsport, mountport = s.enter_context(unfs_server(tmpdir))
+
+            # build core-image-minimal with required packages
+            features = []
+            features.append('IMAGE_FEATURES += "ssh-server-openssh"')
+            features.append('CORE_IMAGE_EXTRA_INSTALL += "{0}"'.format(" ".join(self.default_installed_packages)))
+            self.write_config("\n".join(features))
+            bitbake("core-image-minimal")
+
+            # start runqemu
+            qemu = s.enter_context(runqemu("core-image-minimal", runqemuparams = "nographic"))
+
+            # validate that SSH is working
+            status, _ = qemu.run("uname")
+            self.assertEqual(status, 0)
+
+            # setup nfs mount
+            if qemu.run("mkdir -p \"{0}\"".format(tmpdir))[0] != 0:
+                raise Exception("Failed to setup NFS mount directory on target")
+            mountcmd = "mount -o noac,nfsvers=3,port={0},udp,mountport={1} \"{2}:{3}\" \"{3}\"".format(nfsport, mountport, qemu.server_ip, tmpdir)
+            status, output = qemu.run(mountcmd)
+            if status != 0:
+                raise Exception("Failed to setup NFS mount on target ({})".format(repr(output)))
+
+            super().glibc_run_check(ssh = qemu.ip)
+

---
2.23.0.rc1

#13 lore raw

PATCH 11/11 scripts/lib/resulttool/report.py: Add more result types

In reply to Nathan Rossi

Add additional result types into the dictionary to handle dejagnu style test results. These include PASS, FAIL, XPASS, XFAIL, UNSUPPORTED, UNTESTED, UNRESOLVED and ERROR.

---
 scripts/lib/resulttool/report.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
scripts/lib/resulttool/report.py +3 -3
index f706280aa7..8b03717d29 100644
@@ -19,9 +19,9 @@ class ResultsTextReport(object):
         self.ptests = {}
         self.ltptests = {}
         self.ltpposixtests = {}
-        self.result_types = {'passed': ['PASSED', 'passed'],
-                             'failed': ['FAILED', 'failed', 'ERROR', 'error', 'UNKNOWN'],
-                             'skipped': ['SKIPPED', 'skipped']}
+        self.result_types = {'passed': ['PASSED', 'passed', 'PASS', 'XFAIL'],
+                             'failed': ['FAILED', 'failed', 'FAIL', 'ERROR', 'error', 'UNKNOWN', 'XPASS'],
+                             'skipped': ['SKIPPED', 'skipped', 'UNSUPPORTED', 'UNTESTED', 'UNRESOLVED']}
 
 
     def handle_ptest_result(self, k, status, result, machine):

---
2.23.0.rc1