diff --git a/meta-oniro-core/recipes-core/packagegroups/packagegroup-oniro-tests.bb b/meta-oniro-core/recipes-core/packagegroups/packagegroup-oniro-tests.bb
index 2cdb2c0b8c0fa1544f628840c6a40c1e50635205..be21701a61d6b618e5d1388de0f371f79dcdef39 100644
--- a/meta-oniro-core/recipes-core/packagegroups/packagegroup-oniro-tests.bb
+++ b/meta-oniro-core/recipes-core/packagegroups/packagegroup-oniro-tests.bb
@@ -12,4 +12,5 @@ PACKAGES = "\
 
 RDEPENDS:packagegroup-oniro-tests = "\
 	ptest-runner \
+	python3-checkbox-ng-service \
         "
diff --git a/meta-oniro-core/recipes-devtools/python/python3-requests_2.28.1.bb b/meta-oniro-core/recipes-devtools/python/python3-requests_2.28.1.bb
new file mode 100644
index 0000000000000000000000000000000000000000..ec81f333f2ae0de2b4633b3a6671814e5b66221b
--- /dev/null
+++ b/meta-oniro-core/recipes-devtools/python/python3-requests_2.28.1.bb
@@ -0,0 +1,31 @@
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+DESCRIPTION = "Python HTTP for Humans."
+HOMEPAGE = "https://github.com/psf/requests"
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=34400b68072d710fecd0a2940a0d1658"
+
+SRC_URI[sha256sum] = "7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"
+
+inherit pypi setuptools3
+
+RDEPENDS:${PN} += " \
+    ${PYTHON_PN}-email \
+    ${PYTHON_PN}-json \
+    ${PYTHON_PN}-ndg-httpsclient \
+    ${PYTHON_PN}-netserver \
+    ${PYTHON_PN}-pyasn1 \
+    ${PYTHON_PN}-pyopenssl \
+    ${PYTHON_PN}-pysocks \
+    ${PYTHON_PN}-urllib3 \
+    ${PYTHON_PN}-chardet \
+    ${PYTHON_PN}-charset-normalizer \
+    ${PYTHON_PN}-certifi \
+    ${PYTHON_PN}-idna \
+"
+
+CVE_PRODUCT = "cpe:2.3:a:python:requests:*:*:*:*:*:*:*:*"
+
+BBCLASSEXTEND = "native nativesdk"
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-charset-normalizer_2.1.0.bb b/meta-oniro-staging/recipes-extended/python3/python3-charset-normalizer_2.1.0.bb
new file mode 100644
index 0000000000000000000000000000000000000000..986f0eaf63303531cd461eecdd5bcd8b12967b17
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-charset-normalizer_2.1.0.bb
@@ -0,0 +1,20 @@
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+SUMMARY = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+HOMEPAGE = "https://github.com/ousret/charset_normalizer"
+
+LICENSE = "MIT"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=0974a390827087287db39928f7c524b5"
+
+SRC_URI[sha256sum] = "575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"
+
+inherit pypi setuptools3
+
+RDEPENDS:${PN} += " \
+	${PYTHON_PN}-core \
+	${PYTHON_PN}-logging \
+	${PYTHON_PN}-codecs \
+	${PYTHON_PN}-json \
+"
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-autoescape-for-Jinja2.patch b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-autoescape-for-Jinja2.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f1c4ef820fab800677e5b6278d49bc97749dce64
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-autoescape-for-Jinja2.patch
@@ -0,0 +1,45 @@
+From 916a9f6d3bae6bea1639a83bce67e17393b11d85 Mon Sep 17 00:00:00 2001
+From: Le Van Quach <levan.quach@kalpa.it>
+Date: Fri, 5 Aug 2022 16:56:18 +0200
+Subject: [PATCH] Adjust autoescape for Jinja2
+
+Autoescape extension is called only if jinja2 version is < 2.9
+
+Upstream-Status: Submitted [https://code.launchpad.net/~levanquach/checkbox-ng/+git/checkbox-ng/+merge/429157]
+
+Signed-off-by: Le Van Quach <levan.quach@kalpa.it>
+
+---
+ plainbox/impl/exporter/jinja2.py | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/plainbox/impl/exporter/jinja2.py b/plainbox/impl/exporter/jinja2.py
+index a787b57..abdba4c 100644
+--- a/plainbox/impl/exporter/jinja2.py
++++ b/plainbox/impl/exporter/jinja2.py
+@@ -27,8 +27,10 @@
+ 
+ import json
+ import re
++import jinja2
+ from collections import OrderedDict
+ from datetime import datetime
++from packaging import version
+ 
+ from jinja2 import Environment
+ from jinja2 import FileSystemLoader
+@@ -110,7 +112,13 @@ class Jinja2SessionStateExporter(SessionStateExporterBase):
+         self.option_list = tuple(exporter_unit.option_list or ()) + tuple(
+                 option_list or ())
+         loader = FileSystemLoader(paths)
+-        env = Environment(loader=loader, extensions=['jinja2.ext.autoescape'])
++        # For jinja2 version > 2.9.0 autoescape functionality is built-in,
++        # no need to add extensions
++        if version.parse(jinja2.__version__) >= version.parse('2.9.0'):
++            env = Environment(loader=loader)
++        else:
++            env = Environment(loader=loader, extensions=['jinja2.ext.autoescape'])
++
+         self.customize_environment(env)
+ 
+         def include_file(name):
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-for-deprecated-jinja2.Markup-alias.patch b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-for-deprecated-jinja2.Markup-alias.patch
new file mode 100644
index 0000000000000000000000000000000000000000..14c00a48dde331741e991915a07ca69104eb34df
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Adjust-for-deprecated-jinja2.Markup-alias.patch
@@ -0,0 +1,35 @@
+From 993558aeba06593245d7312a311f184a4c6474fa Mon Sep 17 00:00:00 2001
+From: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+Date: Wed, 13 Jul 2022 15:49:13 +0200
+Subject: [PATCH 1/3] Adjust for deprecated jinja2.Markup alias
+
+The alias was removed by upstream jinja2 commit
+824b4d3e5bb789cabd7cef74e57f4d802a7b2bfd "remove deprecated Markup and
+escape aliases". Upstream recommends importing Markup from the
+markupsafe package instead.
+
+Upstream-Status: Submitted [https://code.launchpad.net/~levanquach/checkbox-ng/+git/checkbox-ng/+merge/429157]
+
+Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+---
+ plainbox/impl/exporter/jinja2.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/plainbox/impl/exporter/jinja2.py b/plainbox/impl/exporter/jinja2.py
+index 1f780e4b..f49059ea 100644
+--- a/plainbox/impl/exporter/jinja2.py
++++ b/plainbox/impl/exporter/jinja2.py
+@@ -32,9 +32,9 @@ from datetime import datetime
+ 
+ from jinja2 import Environment
+ from jinja2 import FileSystemLoader
+-from jinja2 import Markup
+ from jinja2 import environmentfilter
+ from jinja2 import escape
++from markupsafe import Markup
+ 
+ from plainbox import get_version_string
+ from plainbox.abc import ISessionStateExporter
+-- 
+2.34.1
+
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Modify-restart-logic-in-order-to-run-checkbox-servic.patch b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Modify-restart-logic-in-order-to-run-checkbox-servic.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3cedf61c3df290f00e265a591de4b9c3ae2eb7f8
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0001-Modify-restart-logic-in-order-to-run-checkbox-servic.patch
@@ -0,0 +1,54 @@
+From f9505cb839ef8d01b85e72dbc55d119ca223e985 Mon Sep 17 00:00:00 2001
+From: Le Van Quach <levan.quach@kalpa.it>
+Date: Fri, 29 Jul 2022 16:38:06 +0200
+Subject: [PATCH] Modify restart logic in order to run checkbox service at
+ startup for Oniro
+
+Upstream-Status: Submitted [https://code.launchpad.net/~levanquach/checkbox-ng/+git/checkbox-ng/+merge/429157]
+
+Signed-off-by: Le Van Quach <levan.quach@kalpa.it>
+---
+ plainbox/impl/session/restart.py | 20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+diff --git a/plainbox/impl/session/restart.py b/plainbox/impl/session/restart.py
+index 0aa67b4..d7f95b4 100644
+--- a/plainbox/impl/session/restart.py
++++ b/plainbox/impl/session/restart.py
+@@ -276,13 +276,8 @@ def detect_restart_strategy(session=None, session_type=None) -> IRestartStrategy
+     # with the next release or when we do inclusive naming refactor
+     # or roughly after April of 2022
+     if session_type in ('remote', 'checkbox-slave'):
+-        try:
+-            subprocess.run(
+-                ['systemctl', 'is-active', '--quiet', 'checkbox-ng.service'],
+-                check=True)
++        if check_service_is_active():
+             return RemoteDebRestartStrategy()
+-        except subprocess.CalledProcessError:
+-                pass
+ 
+     # XXX: RemoteSnappyRestartStrategy debug
+     remote_restart_stragegy_debug = os.getenv('REMOTE_RESTART_DEBUG')
+@@ -337,8 +332,21 @@ def detect_restart_strategy(session=None, session_type=None) -> IRestartStrategy
+         # NOTE: Assume this is a terminal application
+         return XDGRestartStrategy(app_terminal=True)
+ 
++    # Systemctl
++    if session_type == None:
++        if check_service_is_active():
++            return RemoteDebRestartStrategy()
++
+     raise LookupError("Unable to find appropriate strategy.""")
+ 
++def check_service_is_active() -> bool:
++    try:
++        subprocess.run(
++            ['systemctl', 'is-active', '--quiet', 'checkbox-ng.service'],
++            check=True)
++        return True
++    except subprocess.CalledProcessError:
++        return False
+ 
+ def get_strategy_by_name(name: str) -> type:
+     """
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0002-Adjust-for-deprecated-jinja2.environmentfilter-alias.patch b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0002-Adjust-for-deprecated-jinja2.environmentfilter-alias.patch
new file mode 100644
index 0000000000000000000000000000000000000000..a9ee2ff12e005aa236d416f1533e19b52a359a96
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0002-Adjust-for-deprecated-jinja2.environmentfilter-alias.patch
@@ -0,0 +1,39 @@
+From 782330711cbb58065c47ab9b497cbbc1195f99e7 Mon Sep 17 00:00:00 2001
+From: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+Date: Wed, 13 Jul 2022 17:07:16 +0200
+Subject: [PATCH 2/3] Adjust for deprecated jinja2.environmentfilter alias
+
+This is now called pass_environment.
+
+Upstream-Status: Submitted [https://code.launchpad.net/~levanquach/checkbox-ng/+git/checkbox-ng/+merge/429157]
+
+Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+---
+ plainbox/impl/exporter/jinja2.py | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/plainbox/impl/exporter/jinja2.py b/plainbox/impl/exporter/jinja2.py
+index f49059ea..5980bafa 100644
+--- a/plainbox/impl/exporter/jinja2.py
++++ b/plainbox/impl/exporter/jinja2.py
+@@ -32,7 +32,7 @@ from datetime import datetime
+ 
+ from jinja2 import Environment
+ from jinja2 import FileSystemLoader
+-from jinja2 import environmentfilter
++from jinja2 import pass_environment
+ from jinja2 import escape
+ from markupsafe import Markup
+ 
+@@ -47,7 +47,7 @@ from plainbox.impl.unit.exporter import ExporterError
+ CERTIFICATION_NS = 'com.canonical.certification::'
+ 
+ 
+-@environmentfilter
++@pass_environment
+ def do_strip_ns(_environment, unit_id, ns=CERTIFICATION_NS):
+     """Remove the namespace part of the identifier."""
+     # com.my.namespace::category/job-id → category/job-id
+-- 
+2.34.1
+
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0003-Adjust-for-jinja2.escape-alias.patch b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0003-Adjust-for-jinja2.escape-alias.patch
new file mode 100644
index 0000000000000000000000000000000000000000..40062a445383a376bf978229804bcc888b4a9869
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/0003-Adjust-for-jinja2.escape-alias.patch
@@ -0,0 +1,31 @@
+From c9c09d577dde44816ca92ff595aeb043930eafdb Mon Sep 17 00:00:00 2001
+From: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+Date: Wed, 13 Jul 2022 17:09:13 +0200
+Subject: [PATCH 3/3] Adjust for jinja2.escape alias
+
+This is now called markupsafe.escape
+
+Upstream-Status: Submitted [https://code.launchpad.net/~levanquach/checkbox-ng/+git/checkbox-ng/+merge/429157]
+
+Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@huawei.com>
+---
+ plainbox/impl/exporter/jinja2.py | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/plainbox/impl/exporter/jinja2.py b/plainbox/impl/exporter/jinja2.py
+index 5980bafa..a787b576 100644
+--- a/plainbox/impl/exporter/jinja2.py
++++ b/plainbox/impl/exporter/jinja2.py
+@@ -33,8 +33,7 @@ from datetime import datetime
+ from jinja2 import Environment
+ from jinja2 import FileSystemLoader
+ from jinja2 import pass_environment
+-from jinja2 import escape
+-from markupsafe import Markup
++from markupsafe import escape, Markup
+ 
+ from plainbox import get_version_string
+ from plainbox.abc import ISessionStateExporter
+-- 
+2.34.1
+
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/checkbox-ng.service b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/checkbox-ng.service
new file mode 100644
index 0000000000000000000000000000000000000000..fe8d009aad86e1f0dce872ee328cbedc54c92a4e
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/checkbox-ng.service
@@ -0,0 +1,19 @@
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+[Unit]
+Description=Checkbox Remote Service
+Wants=network.target
+Requires=run-mount-appdata.mount
+
+[Service]
+ExecStart=/usr/bin/checkbox-cli service
+SyslogIdentifier=checkbox-ng.service
+Environment="XDG_CACHE_HOME=/run/mount/appdata/checkbox-ng/
+Restart=on-failure
+TimeoutStopSec=30
+Type=simple
+
+[Install]
+WantedBy=multi-user.target
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/oniro-tests b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/oniro-tests
new file mode 100644
index 0000000000000000000000000000000000000000..3a33ff220e76b401b10419c4c7932b2ec43109d1
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng/oniro-tests
@@ -0,0 +1,45 @@
+#!/usr/bin/env checkbox-cli
+#
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+[launcher]
+launcher_version = 1
+stock_reports = text, certification
+
+[exporter:html]
+unit = com.canonical.plainbox::html
+
+[exporter:tar]
+unit = com.canonical.plainbox::tar
+
+[exporter:junit]
+unit = com.canonical.plainbox::junit
+
+[transport:html_transport]
+type = file
+path = /run/mount/appdata/oniro-tests-report.html
+
+[transport:tar_transport]
+type = file
+path = /run/mount/appdata/oniro-tests-report.tar.xz
+
+[transport:junit_transport]
+type = file
+path = /run/mount/appdata/oniro-tests-report.junit
+
+[report:html_report]
+transport = html_transport
+exporter = html
+forced = yes
+
+[report:tar_report]
+transport = tar_transport
+exporter = tar
+forced = yes
+
+[report:junit_report]
+transport = junit_transport
+exporter = junit
+forced = yes
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng_1.18.1.bb b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng_1.18.1.bb
new file mode 100644
index 0000000000000000000000000000000000000000..cbb255e33ffa30859930bfd66e1b5ebfb848b8cc
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-checkbox-ng_1.18.1.bb
@@ -0,0 +1,51 @@
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+SUMMARY = "Checkbox-ng is a hardware testing tool useful for certifying laptops, desktops, servers and IOT devices with Ubuntu."
+HOMEPAGE = "https://launchpad.net/checkbox-project"
+
+LICENSE = "GPL-3.0-only"
+LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
+
+SRC_URI[sha256sum] = "6be1033802167ab2f7dfb21a47e76e326152dd8441ba8d6f6d0765f06bbc67e5"
+
+SRC_URI += "file://0001-Adjust-for-deprecated-jinja2.Markup-alias.patch \
+           file://0002-Adjust-for-deprecated-jinja2.environmentfilter-alias.patch \
+           file://0003-Adjust-for-jinja2.escape-alias.patch \
+           file://checkbox-ng.service \
+           file://0001-Modify-restart-logic-in-order-to-run-checkbox-servic.patch \
+           file://0001-Adjust-autoescape-for-Jinja2.patch \
+           file://oniro-tests \
+           "
+
+inherit pypi setuptools3
+
+RDEPENDS:${PN} += " \
+	${PYTHON_PN}-core \
+	${PYTHON_PN}-jinja2 \
+	${PYTHON_PN}-pkg-resources \
+	${PYTHON_PN}-psutil \
+	${PYTHON_PN}-requests \
+	${PYTHON_PN}-tqdm \
+	${PYTHON_PN}-urwid \
+	${PYTHON_PN}-xlsxwriter \
+"
+
+# The checkbox-ng-service is a remotely accessible network service used by
+# checkbox in some testing scenarios.
+
+inherit systemd
+
+PACKAGES =+ "${PN}-service"
+SYSTEMD_PACKAGES = "${PN}-service"
+SYSTEMD_SERVICE:${PN}-service = "checkbox-ng.service"
+
+do_install:append() {
+    install -D -m 0644 ${WORKDIR}/checkbox-ng.service -t ${D}${systemd_unitdir}/system/
+    install -D -m 0755 ${WORKDIR}/oniro-tests -t ${D}${bindir}
+}
+
+RDEPENDS:${PN}-service += " \
+    ${PN} \
+"
diff --git a/meta-oniro-staging/recipes-extended/python3/python3-urwid_2.1.2.bb b/meta-oniro-staging/recipes-extended/python3/python3-urwid_2.1.2.bb
new file mode 100644
index 0000000000000000000000000000000000000000..bc13e7a141dfd24815215d96c2c8a1499747fbcf
--- /dev/null
+++ b/meta-oniro-staging/recipes-extended/python3/python3-urwid_2.1.2.bb
@@ -0,0 +1,23 @@
+# SPDX-FileCopyrightText: Le Van Quach <levan.quach@kalpa.it>
+#
+# SPDX-License-Identifier: MIT
+
+SUMMARY = "Urwid is a console user interface library for Python."
+HOMEPAGE = "http://urwid.org"
+
+LICENSE = "LGPL-2.1-or-later"
+LIC_FILES_CHKSUM = "file://COPYING;md5=243b725d71bb5df4a1e5920b344b86ad"
+
+SRC_URI[sha256sum] = "588bee9c1cb208d0906a9f73c613d2bd32c3ed3702012f51efe318a3f2127eae"
+
+inherit pypi setuptools3
+
+RDEPENDS:${PN} += " \
+	${PYTHON_PN}-codecs \
+	${PYTHON_PN}-core \
+	${PYTHON_PN}-curses \
+	${PYTHON_PN}-datetime \
+	${PYTHON_PN}-io \
+	${PYTHON_PN}-math \
+	${PYTHON_PN}-shell \
+"