diff mbox series

icu: Add ptest support

Message ID 20250704053856.2446627-1-yamane07ynct@gmail.com
State New
Headers show
Series icu: Add ptest support | expand

Commit Message

Daisuke Yamane July 4, 2025, 5:38 a.m. UTC
Add following patches.
  - 0001-test-Add-support-ptest.patch
    - Some default paths in test code are invalid at runtime and cause
    - test failures. So add a patch to adjust path to test data for ptest
    - environment.
  - 0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch
    - Since ICU-77.1, a test case (TestLargeMemory) that fails to build
    - in a 32-bit environment. So add a patch to skip this test case.
    - This bug has been reported to upstream. See https://unicode-org.atlassian.net/browse/ICU-23120.
Install icu test-suite to run it as a ptest.
Add icu-ptest to PTERSTS_SLOW because it takes more than 30s to complete
on qemuarm64.

root@qemuarm64:~# ptest-runner icu
START: ptest-runner
2025-07-02T17:48
BEGIN: /usr/lib/icu/ptest
___(snip)___
[All tests passed successfully...]
Elapsed Time: 00:01:10.345
PASS: cintltst
----------------------------------------
ALL TESTS SUMMARY:
All tests OK:  intltest iotest cintltst
DURATION: 371
END: /usr/lib/icu/ptest
2025-07-03T18:44
STOP: ptest-runner
TOTAL: 1 FAIL: 0

Signed-off-by: Daisuke Yamane <yamane07ynct@gmail.com>
---
 .../distro/include/ptest-packagelists.inc     |  1 +
 ...nicodeStringTest-TestLargeMemory-on-.patch | 28 +++++++
 .../icu/icu/0001-test-Add-support-ptest.patch | 84 +++++++++++++++++++
 meta/recipes-support/icu/icu/run-ptest        | 40 +++++++++
 meta/recipes-support/icu/icu_77-1.bb          | 26 ++++++
 5 files changed, 179 insertions(+)
 create mode 100644 meta/recipes-support/icu/icu/0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch
 create mode 100644 meta/recipes-support/icu/icu/0001-test-Add-support-ptest.patch
 create mode 100755 meta/recipes-support/icu/icu/run-ptest

Comments

Alexander Kanavin July 4, 2025, 8:49 a.m. UTC | #1
On Fri, 4 Jul 2025 at 07:40, Daisuke Yamane via lists.openembedded.org
<yamane07ynct=gmail.com@lists.openembedded.org> wrote:

> Add icu-ptest to PTERSTS_SLOW because it takes more than 30s to complete
> on qemuarm64.

Was this on an arm64 host with kvm enabled in via runqemu option?
Otherwise the measurement isn't correct, as it goes through software
emulation and is a lot slower than the actual CI execution.

If your host is x86_64, then you need to build for qemux86_64, and run
that with kvm.

> +#!/bin/sh
> +
> +TESTS="intltest iotest cintltst"
> +TMP="$(mktemp -d)"
> +STATUS_R="${TMP}/status.$$"
> +TOPDIR=$(dirname "$(realpath $0)")
> +for t in ${TESTS}; do
> +       cd ${TOPDIR}/test/$t
> +       ./$t -E${STATUS_R}.$t || (echo "FAIL: $t"; touch ${STATUS_R}.$t; cp ${STATUS_R}.$t ${STATUS_R}.$t.FAIL)
> +       [ ! -f ${STATUS_R}.$t.FAIL ] && touch ${STATUS_R}.$t.PASS && echo "PASS: $t"
> +       echo "----------------------------------------"
> +       if [ -s "${STATUS_R}.$t.FAIL" ];then
> +               echo "-------------"
> +               echo "| ***     FAILING TEST SUMMARY FOR:              $t"
> +               cat ${STATUS_R}.$t.FAIL
> +               echo "| *** END FAILING TEST SUMMARY FOR:              $t"
> +       fi
> +done
> +
> +goods=""
> +bads=""
> +for t in ${TESTS}; do
> +       if [ -f "${STATUS_R}.$t.FAIL" ];then
> +               bads="${bads} $t"
> +       elif [ -f "${STATUS_R}.$t.PASS" ];then
> +               goods="${goods} $t"
> +       else
> +               echo "*** subtest did not complete - $t"
> +               bads="${bads} $t"
> +       fi
> +done
> +echo "ALL TESTS SUMMARY:"
> +if [ ! "x${bads}" = "x" ];then
> +       echo "ok: ${goods}"
> +       echo "===== ERRS: ${bads}"
> +       exit 1
> +else
> +       echo "All tests OK: ${goods}"
> +fi

This is a direct copy-paste of the icu Makefile:
https://github.com/unicode-org/icu/blob/main/icu4c/source/test/Makefile.in

I don't think it's necessary to make it this complicated (and
potentially have to keep it in sync with the Makefile), we can perhaps
just run the tests, and see what they print; if PASS/FAIL isn't there,
then the script can add that.

> +do_install_ptest() {
> +    install -d ${D}${PTEST_PATH}/test
> +    install -d ${D}${PTEST_PATH}/data
> +    cp -r ${S}/test/testdata ${D}/${PTEST_PATH}/test
> +    cp -r ${S}/data/unidata ${D}/${PTEST_PATH}/data/
> +    cp -r ${S}/data/sprep ${D}/${PTEST_PATH}/data/
> +    cp -r ${S}/../testdata ${D}/${PTEST_PATH}/
> +    cp -r ${B}/test/testdata/out ${D}/${PTEST_PATH}/test/testdata
> +
> +    list="intltest iotest cintltst"
> +    for i in $list; do
> +        install -d ${D}${PTEST_PATH}/test/${i}/
> +        install -m 755 ${B}/test/${i}/${i} ${D}/${PTEST_PATH}/test/${i}/
> +    done
> +}

The same Makefile linked above has a rule for installing the tests.
Can that be used instead? Maybe it also installs some way to run them?

In any case, do not hardcode the particular test names; that changes
over time, and it's better to have some dynamic way of installing
(e.g. by file name pattern or executable bit).

Alex
Daisuke Yamane July 5, 2025, 6:50 p.m. UTC | #2
2025年7月4日(金) 17:49 Alexander Kanavin <alex.kanavin@gmail.com>:
>
> On Fri, 4 Jul 2025 at 07:40, Daisuke Yamane via lists.openembedded.org
> <yamane07ynct=gmail.com@lists.openembedded.org> wrote:
>
> > Add icu-ptest to PTERSTS_SLOW because it takes more than 30s to complete
> > on qemuarm64.
>
> Was this on an arm64 host with kvm enabled in via runqemu option?
> Otherwise the measurement isn't correct, as it goes through software
> emulation and is a lot slower than the actual CI execution.
>
> If your host is x86_64, then you need to build for qemux86_64, and run
> that with kvm.

Enabling KVM on qemux86_64 and running ptest, the intltest test was
intrrupted due to oom-killer.
(I'm not sure why, but it seems that qemuarm64 didn't trigger the oom-killer.)

|          TestBug22584 {
| [   30.217322] intltest invoked oom-killer:
| gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0,
| oom_score_adj=0
| [   30.217717] CPU: 2 UID: 0 PID: 278 Comm: intltest Not tainted
| 6.12.31-yocto-standard #1
| [   30.217719] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
| BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014

Increasing the memory for qemux86_64 from 256MB to 512MB caused the
test to pass in 28 seconds.
In this case, should I add icu to PTESTS_PROBLEMS, or add a patch to
skip tests that fail and add icu to PTEST_FAST?

>
> > +#!/bin/sh
> > +
> > +TESTS="intltest iotest cintltst"
> > +TMP="$(mktemp -d)"
> > +STATUS_R="${TMP}/status.$$"
> > +TOPDIR=$(dirname "$(realpath $0)")
> > +for t in ${TESTS}; do
> > +       cd ${TOPDIR}/test/$t
> > +       ./$t -E${STATUS_R}.$t || (echo "FAIL: $t"; touch ${STATUS_R}.$t; cp ${STATUS_R}.$t ${STATUS_R}.$t.FAIL)
> > +       [ ! -f ${STATUS_R}.$t.FAIL ] && touch ${STATUS_R}.$t.PASS && echo "PASS: $t"
> > +       echo "----------------------------------------"
> > +       if [ -s "${STATUS_R}.$t.FAIL" ];then
> > +               echo "-------------"
> > +               echo "| ***     FAILING TEST SUMMARY FOR:              $t"
> > +               cat ${STATUS_R}.$t.FAIL
> > +               echo "| *** END FAILING TEST SUMMARY FOR:              $t"
> > +       fi
> > +done
> > +
> > +goods=""
> > +bads=""
> > +for t in ${TESTS}; do
> > +       if [ -f "${STATUS_R}.$t.FAIL" ];then
> > +               bads="${bads} $t"
> > +       elif [ -f "${STATUS_R}.$t.PASS" ];then
> > +               goods="${goods} $t"
> > +       else
> > +               echo "*** subtest did not complete - $t"
> > +               bads="${bads} $t"
> > +       fi
> > +done
> > +echo "ALL TESTS SUMMARY:"
> > +if [ ! "x${bads}" = "x" ];then
> > +       echo "ok: ${goods}"
> > +       echo "===== ERRS: ${bads}"
> > +       exit 1
> > +else
> > +       echo "All tests OK: ${goods}"
> > +fi
>
> This is a direct copy-paste of the icu Makefile:
> https://github.com/unicode-org/icu/blob/main/icu4c/source/test/Makefile.in
>
> I don't think it's necessary to make it this complicated (and
> potentially have to keep it in sync with the Makefile), we can perhaps
> just run the tests, and see what they print; if PASS/FAIL isn't there,
> then the script can add that.

Got it. In v2, I'll simplify the script so that it just confirms the results.

>
> > +do_install_ptest() {
> > +    install -d ${D}${PTEST_PATH}/test
> > +    install -d ${D}${PTEST_PATH}/data
> > +    cp -r ${S}/test/testdata ${D}/${PTEST_PATH}/test
> > +    cp -r ${S}/data/unidata ${D}/${PTEST_PATH}/data/
> > +    cp -r ${S}/data/sprep ${D}/${PTEST_PATH}/data/
> > +    cp -r ${S}/../testdata ${D}/${PTEST_PATH}/
> > +    cp -r ${B}/test/testdata/out ${D}/${PTEST_PATH}/test/testdata
> > +
> > +    list="intltest iotest cintltst"
> > +    for i in $list; do
> > +        install -d ${D}${PTEST_PATH}/test/${i}/
> > +        install -m 755 ${B}/test/${i}/${i} ${D}/${PTEST_PATH}/test/${i}/
> > +    done
> > +}
>
> The same Makefile linked above has a rule for installing the tests.
> Can that be used instead? Maybe it also installs some way to run them?
>
> In any case, do not hardcode the particular test names; that changes
> over time, and it's better to have some dynamic way of installing
> (e.g. by file name pattern or executable bit).

Indeed, there is an install rule in Makefile.in, but since no
installation process is actually implemented, it cannot be used.
In v2, I will detect executable binaries in the test directory and install them.

>
> Alex
Alexander Kanavin July 5, 2025, 7:01 p.m. UTC | #3
On Sat, 5 Jul 2025 at 20:50, Daisuke Yamane <yamane07ynct@gmail.com> wrote:
> Enabling KVM on qemux86_64 and running ptest, the intltest test was
> intrrupted due to oom-killer.
> (I'm not sure why, but it seems that qemuarm64 didn't trigger the oom-killer.)
>
> |          TestBug22584 {
> | [   30.217322] intltest invoked oom-killer:
> | gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0,
> | oom_score_adj=0
> | [   30.217717] CPU: 2 UID: 0 PID: 278 Comm: intltest Not tainted
> | 6.12.31-yocto-standard #1
> | [   30.217719] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
> | BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
>
> Increasing the memory for qemux86_64 from 256MB to 512MB caused the
> test to pass in 28 seconds.
> In this case, should I add icu to PTESTS_PROBLEMS, or add a patch to
> skip tests that fail and add icu to PTEST_FAST?

Neither. The correct way to run ptests is to build
core-image-ptest-icu image, and use that with runqemu, rather than add
the ptest package to some stock image (which I assume you've done
until now). This would also match how autobuilder is going to run
ptests, so any issues it would have can be directly reproduced.

As you can see in meta/recipes-core/images/core-image-ptest.bb, ptest
images by default have 1G of RAM, and that can be increased further
per ptest.

Alex
diff mbox series

Patch

diff --git a/meta/conf/distro/include/ptest-packagelists.inc b/meta/conf/distro/include/ptest-packagelists.inc
index 4253c7b062..ac767b5cd3 100644
--- a/meta/conf/distro/include/ptest-packagelists.inc
+++ b/meta/conf/distro/include/ptest-packagelists.inc
@@ -105,6 +105,7 @@  PTESTS_SLOW = "\
     glib-2.0 \
     gnutls \
     gstreamer1.0 \
+    icu \
     less \
     libevent \
     libgcrypt \
diff --git a/meta/recipes-support/icu/icu/0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch b/meta/recipes-support/icu/icu/0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch
new file mode 100644
index 0000000000..e2e9546679
--- /dev/null
+++ b/meta/recipes-support/icu/icu/0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch
@@ -0,0 +1,28 @@ 
+From 4b3e6888c2aaba6465f1bc96f61b17a2513050f3 Mon Sep 17 00:00:00 2001
+From: David Seifert <soap@gentoo.org>
+Date: Sat, 21 Jun 2025 12:28:15 +0200
+Subject: [PATCH] ICU-23120 Mask UnicodeStringTest::TestLargeMemory on 32-bit
+ platforms
+
+Upstream-Status: Submitted [https://github.com/unicode-org/icu/pull/3496]
+Signed-off-by: Daisuke Yamane <yamane07ynct@gmail.com>
+---
+ test/intltest/ustrtest.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/test/intltest/ustrtest.cpp b/test/intltest/ustrtest.cpp
+index 56976b3e3d2..26225f5b5b5 100644
+--- a/test/intltest/ustrtest.cpp
++++ b/test/intltest/ustrtest.cpp
+@@ -2353,7 +2353,7 @@ void UnicodeStringTest::TestUnicodeStringInsertAppendToSelf() {
+ }
+ 
+ void UnicodeStringTest::TestLargeMemory() {
+-#if U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED
++#if (U_PLATFORM_IS_LINUX_BASED || U_PLATFORM_IS_DARWIN_BASED) && (UINTPTR_MAX == 0xFFFFFFFFFFFFFFFF)
+     if(quick) { return; }
+     IcuTestErrorCode status(*this, "TestLargeMemory");
+     constexpr uint32_t len = 2147483643;
+-- 
+2.43.0
+
diff --git a/meta/recipes-support/icu/icu/0001-test-Add-support-ptest.patch b/meta/recipes-support/icu/icu/0001-test-Add-support-ptest.patch
new file mode 100644
index 0000000000..9f7520c9d3
--- /dev/null
+++ b/meta/recipes-support/icu/icu/0001-test-Add-support-ptest.patch
@@ -0,0 +1,84 @@ 
+From 783d9e0d3d7824fbca53c2c3a80e8e5e23eacc82 Mon Sep 17 00:00:00 2001
+From: Daisuke Yamane <yamane07ynct@gmail.com>
+Date: Tue, 1 Jul 2025 18:35:25 +0900
+Subject: [PATCH] test: Add support ptest
+
+Upstream-Status: Inappropriate [oe-core specific]
+
+Signed-off-by: Daisuke Yamane <yamane07ynct@gmail.com>
+---
+ test/cintltst/Makefile.in  | 2 +-
+ test/intltest/Makefile.in  | 2 +-
+ test/intltest/intltest.cpp | 2 +-
+ test/iotest/Makefile.in    | 2 +-
+ test/letest/Makefile.in    | 2 +-
+ 5 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/test/cintltst/Makefile.in b/test/cintltst/Makefile.in
+index 552a105..9cf3071 100644
+--- a/test/cintltst/Makefile.in
++++ b/test/cintltst/Makefile.in
+@@ -39,7 +39,7 @@ CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/ct
+ ifdef QNX_TARGET
+ DEFS += -D'ICU_UNICODE_VERSION="$(UNICODE_VERSION)"' -D'ICU_VERSION="@VERSION@"' -D'ICUDATA_NAME="$(ICUDATA_PLATFORM_NAME)"' -D'U_TOPSRCDIR="/var/icu_tests"' -D'U_TOPBUILDDIR="/var/icu_tests/"'
+ else
+-DEFS += -D'ICU_UNICODE_VERSION="$(UNICODE_VERSION)"' -D'ICU_VERSION="@VERSION@"' -D'ICUDATA_NAME="$(ICUDATA_PLATFORM_NAME)"' -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"'
++DEFS += -D'ICU_UNICODE_VERSION="$(UNICODE_VERSION)"' -D'ICU_VERSION="@VERSION@"' -D'ICUDATA_NAME="$(ICUDATA_PLATFORM_NAME)"' -D'U_TOPSRCDIR="$(PTEST_PATH)/"' -D'U_TOPBUILDDIR="$(PTEST_PATH)/"'
+ endif
+ LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUTOOLUTIL) $(LIBICUUC) $(DEFAULT_LIBS) $(LIB_M)
+ 
+diff --git a/test/intltest/Makefile.in b/test/intltest/Makefile.in
+index 5d4a03b..ca4e4cd 100644
+--- a/test/intltest/Makefile.in
++++ b/test/intltest/Makefile.in
+@@ -39,7 +39,7 @@ CPPFLAGS += -DUNISTR_FROM_CHAR_EXPLICIT= -DUNISTR_FROM_STRING_EXPLICIT=
+ ifdef QNX_TARGET
+ DEFS += -D'U_TOPSRCDIR="/var/icu_tests"' -D'U_TOPBUILDDIR="/var/icu_tests/"'
+ else
+-DEFS += -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"'
++DEFS += -D'U_TOPSRCDIR="$(PTEST_PATH)/"' -D'U_TOPBUILDDIR="$(PTEST_PATH)/"'
+ endif
+ LIBS = $(LIBCTESTFW) $(LIBICUI18N) $(LIBICUUC) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M) $(LIB_THREAD)
+ 
+diff --git a/test/intltest/intltest.cpp b/test/intltest/intltest.cpp
+index 3806d0f..33829b0 100644
+--- a/test/intltest/intltest.cpp
++++ b/test/intltest/intltest.cpp
+@@ -1713,7 +1713,7 @@ static bool fileExists(const char* fileName) {
+  * Returns the path to icu/testdata/
+  */
+ const char *IntlTest::getSharedTestData(UErrorCode& err) {
+-#define SOURCE_TARBALL_TOP U_TOPSRCDIR U_FILE_SEP_STRING ".." U_FILE_SEP_STRING
++#define SOURCE_TARBALL_TOP U_TOPSRCDIR U_FILE_SEP_STRING
+ #define REPO_TOP SOURCE_TARBALL_TOP ".." U_FILE_SEP_STRING
+ #define FILE_NAME U_FILE_SEP_STRING "message2" U_FILE_SEP_STRING "valid-tests.json"
+     const char *srcDataDir = nullptr;
+diff --git a/test/iotest/Makefile.in b/test/iotest/Makefile.in
+index 16c510f..9eeff4b 100644
+--- a/test/iotest/Makefile.in
++++ b/test/iotest/Makefile.in
+@@ -39,7 +39,7 @@ CPPFLAGS += -DUNISTR_FROM_CHAR_EXPLICIT= -DUNISTR_FROM_STRING_EXPLICIT=
+ ifdef QNX_TARGET
+ DEFS += -D'U_TOPSRCDIR="/var/icu_tests"' -D'U_TOPBUILDDIR="/var/icu_tests/"'
+ else
+-DEFS += -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"'
++DEFS += -D'U_TOPSRCDIR="$(PTEST_PATH)/"' -D'U_TOPBUILDDIR="$(PTEST_PATH)/"'
+ endif
+ LIBS = $(LIBCTESTFW) $(LIBICUTOOLUTIL) $(LIBICUIO) $(LIBICUI18N) $(LIBICUUC) $(DEFAULT_LIBS) $(LIB_M)
+ 
+diff --git a/test/letest/Makefile.in b/test/letest/Makefile.in
+index 156c86f..555a820 100644
+--- a/test/letest/Makefile.in
++++ b/test/letest/Makefile.in
+@@ -30,7 +30,7 @@ BUILDDIR := $(BUILDDIR:test\\cintltst/../../=)
+ BUILDDIR := $(BUILDDIR:TEST\\CINTLTST/../../=)
+ 
+ CPPFLAGS += -I$(top_srcdir)/common -I$(top_srcdir)/i18n -I$(top_srcdir)/tools/ctestfw -I$(top_srcdir)/tools/toolutil -I$(top_srcdir)/layoutex $(ICULE_CFLAGS) $(ICULEHB_CFLAGS)
+-DEFS += -D'U_TOPSRCDIR="$(top_srcdir)/"' -D'U_TOPBUILDDIR="$(BUILDDIR)"'
++DEFS += -D'U_TOPSRCDIR="$(PTEST_PATH)/"' -D'U_TOPBUILDDIR="$(PTEST_PATH)/"'
+ LIBS = $(LIBICULX) $(LIBICUUC) $(LIBICUI18N) $(LIBCTESTFW) $(LIBICUTOOLUTIL) $(DEFAULT_LIBS) $(LIB_M) $(ICULEHB_LIBS)
+ 
+ COMMONOBJECTS = SimpleFontInstance.o
+-- 
+2.43.0
+
diff --git a/meta/recipes-support/icu/icu/run-ptest b/meta/recipes-support/icu/icu/run-ptest
new file mode 100755
index 0000000000..9a428cf205
--- /dev/null
+++ b/meta/recipes-support/icu/icu/run-ptest
@@ -0,0 +1,40 @@ 
+#!/bin/sh
+
+TESTS="intltest iotest cintltst"
+TMP="$(mktemp -d)"
+STATUS_R="${TMP}/status.$$"
+TOPDIR=$(dirname "$(realpath $0)")
+for t in ${TESTS}; do
+	cd ${TOPDIR}/test/$t
+	./$t -E${STATUS_R}.$t || (echo "FAIL: $t"; touch ${STATUS_R}.$t; cp ${STATUS_R}.$t ${STATUS_R}.$t.FAIL)
+	[ ! -f ${STATUS_R}.$t.FAIL ] && touch ${STATUS_R}.$t.PASS && echo "PASS: $t"
+	echo "----------------------------------------"
+	if [ -s "${STATUS_R}.$t.FAIL" ];then
+		echo "-------------"
+		echo "| ***     FAILING TEST SUMMARY FOR:              $t"
+		cat ${STATUS_R}.$t.FAIL
+		echo "| *** END FAILING TEST SUMMARY FOR:              $t"
+	fi
+done
+
+goods=""
+bads=""
+for t in ${TESTS}; do
+	if [ -f "${STATUS_R}.$t.FAIL" ];then
+		bads="${bads} $t"
+	elif [ -f "${STATUS_R}.$t.PASS" ];then
+		goods="${goods} $t"
+	else
+		echo "*** subtest did not complete - $t"
+		bads="${bads} $t"
+	fi
+done
+echo "ALL TESTS SUMMARY:"
+if [ ! "x${bads}" = "x" ];then
+	echo "ok: ${goods}"
+	echo "===== ERRS: ${bads}"
+	exit 1
+else
+	echo "All tests OK: ${goods}"
+fi
+rm -rf ${TMP}
diff --git a/meta/recipes-support/icu/icu_77-1.bb b/meta/recipes-support/icu/icu_77-1.bb
index e655b18ad2..6bd3c5d89b 100644
--- a/meta/recipes-support/icu/icu_77-1.bb
+++ b/meta/recipes-support/icu/icu_77-1.bb
@@ -119,6 +119,9 @@  SRC_URI = "${BASE_SRC_URI};name=code \
            ${DATA_SRC_URI};name=data \
            file://filter.json \
            file://0001-icu-Added-armeb-support.patch \
+           file://0001-ICU-23120-Mask-UnicodeStringTest-TestLargeMemory-on-.patch \
+           file://0001-test-Add-support-ptest.patch \
+           file://run-ptest \
            "
 
 SRC_URI:append:class-target = "\
@@ -160,3 +163,26 @@  do_make_icudata() {
 }
 
 addtask make_icudata before do_configure after do_patch do_prepare_recipe_sysroot
+
+inherit ptest
+RDEPENDS:${PN}-ptest += "bash"
+
+do_compile_ptest() {
+    oe_runmake -C test everything PTEST_PATH=${PTEST_PATH}
+}
+
+do_install_ptest() {
+    install -d ${D}${PTEST_PATH}/test
+    install -d ${D}${PTEST_PATH}/data
+    cp -r ${S}/test/testdata ${D}/${PTEST_PATH}/test
+    cp -r ${S}/data/unidata ${D}/${PTEST_PATH}/data/
+    cp -r ${S}/data/sprep ${D}/${PTEST_PATH}/data/
+    cp -r ${S}/../testdata ${D}/${PTEST_PATH}/
+    cp -r ${B}/test/testdata/out ${D}/${PTEST_PATH}/test/testdata
+
+    list="intltest iotest cintltst"
+    for i in $list; do
+        install -d ${D}${PTEST_PATH}/test/${i}/
+        install -m 755 ${B}/test/${i}/${i} ${D}/${PTEST_PATH}/test/${i}/
+    done
+}