Repository navigation
Add support for OpenHarmony platform #3898
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| #!/bin/sh | ||
|
|
||
| # Save the PATH as it was when the test started to restore it when it finishes | ||
| ORIG_PATH="${PATH}" | ||
|
|
||
| cleanup() { | ||
| # Restore the PATH as it was when the test started | ||
| export PATH="${ORIG_PATH}" | ||
| rm -rf "${TMP_DIR}" | ||
| } | ||
|
|
||
| die() { | ||
| cleanup | ||
| echo "$@" | ||
| exit 1 | ||
| } | ||
|
|
||
| : nvm.sh | ||
| \. ../../../nvm.sh | ||
|
|
||
| # Directory where mocked binaries used by nvm_get_os for each OS/arch are located | ||
| MOCKS_DIR="$(pwd)/../../mocks" | ||
|
|
||
| # Sets the PATH for these tests to include the symlinks to the mocked binaries | ||
| export PATH=".:${PATH}" | ||
|
|
||
| TMP_DIR=$(mktemp -d) | ||
|
|
||
| # Setups mock binaries for a given OS and arch that mimic the output of | ||
| # the real binaries used by nvm_get_os to guess the OS of a given system. | ||
| setup_mock_os() { | ||
| local OS | ||
| OS=$1 | ||
| local ARCH | ||
| ARCH=$2 | ||
| ln -sf "${MOCKS_DIR}/uname_${OS}_${ARCH}" ./uname | ||
| } | ||
|
|
||
| # Cleans up the setup done by setup_mock_os. | ||
| cleanup_mock_os() { | ||
| rm -f ./uname | ||
| } | ||
|
|
||
| # Runs nvm_get_os for OS $OS and arch $ARCH, and compares the expected | ||
| # output $EXPECTED_OUTPUT with the actual output. Does nothing and exits | ||
| # cleanly if they match, dies otherwise. | ||
| run_test() { | ||
| local EXPECTED | ||
| EXPECTED=$1 | ||
| local OUTPUT | ||
| OUTPUT="$(nvm_get_os)" | ||
| [ "_${OUTPUT}" = "_${EXPECTED}" ] || | ||
| die "nvm_get_os produced \"${OUTPUT}\", expected \"${EXPECTED}\"" | ||
| } | ||
|
|
||
| # Pre-existing arms | ||
|
|
||
| setup_mock_os linux aarch64 | ||
| run_test "linux" | ||
| cleanup_mock_os | ||
|
|
||
| setup_mock_os osx amd64 | ||
| run_test "darwin" | ||
| cleanup_mock_os | ||
|
|
||
| setup_mock_os smartos amd64 | ||
| run_test "sunos" | ||
| cleanup_mock_os | ||
|
|
||
| # HarmonyOS kernel without OpenHarmony userland | ||
|
|
||
| setup_mock_os harmonyos aarch64 | ||
| run_test "" | ||
| cleanup_mock_os | ||
|
|
||
| # OpenHarmony detection via chroot | ||
|
|
||
| setup_chroot() { | ||
| chroot_dir=$1 | ||
| param_mock=$2 | ||
| uname_mock=$3 | ||
|
|
||
| # Directories | ||
| mkdir -p "${chroot_dir}/etc" | ||
| mkdir -p "${chroot_dir}/bin" | ||
| mkdir -p "${chroot_dir}/usr/bin" | ||
| mkdir -p "${chroot_dir}/lib64" | ||
| mkdir -p "${chroot_dir}/dev" | ||
| mkdir -p "${chroot_dir}/system/bin" | ||
|
|
||
| # Files and binaries | ||
| cp ../../../nvm.sh "${chroot_dir}/" | ||
| cp /bin/sh /usr/bin/dirname /usr/bin/grep "${chroot_dir}/usr/bin/" | ||
| cp "${uname_mock}" "${chroot_dir}/usr/bin/uname" | ||
| chmod +x "${chroot_dir}/usr/bin/uname" | ||
| ln -sf ../usr/bin/sh "${chroot_dir}/bin/sh" | ||
|
|
||
| # Fake OpenHarmony param binary | ||
| cp "${param_mock}" "${chroot_dir}/system/bin/param" | ||
| chmod +x "${chroot_dir}/system/bin/param" | ||
|
|
||
| # Libraries | ||
| for binary in /bin/sh /usr/bin/dirname /usr/bin/uname /usr/bin/grep; do | ||
| for lib in $(ldd $binary | awk '{print $3}' | grep "^/"); do | ||
| dir=$(dirname "${lib}") | ||
| mkdir -p "${chroot_dir}${dir}" | ||
| cp "${lib}" "${chroot_dir}${dir}/" | ||
| done | ||
| done | ||
|
|
||
| # Dynamic linker | ||
| cp /lib64/ld-linux-x86-64.so.2 "${chroot_dir}/lib64/" | ||
|
|
||
| # /dev/null | ||
| sudo mknod "${chroot_dir}/dev/null" c 1 3 | ||
| } | ||
|
|
||
| # The chroot fixtures assume a glibc layout (fixed dynamic-linker path | ||
| # under /lib64, coreutils binaries). On musl Alpine that setup does not | ||
| # apply, and nvm_get_os's OpenHarmony probe cannot be exercised there; | ||
| # skip the chroot checks on Alpine. | ||
| if [ -f "/etc/alpine-release" ]; then | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This skips the whole block on every Alpine lane, and the four arms that remain pass byte-identically with the entire nvm.sh hunk deleted. 24 of the 32 One arm closes most of that without a chroot, so it runs everywhere: # openharmony + aarch64 composes the slug a mirror has to serve
ln -sf "${MOCKS_DIR}/uname_linux_aarch64" ./uname
nvm_get_os() { nvm_echo openharmony; }
SLUG="$(nvm_get_download_slug node binary v22.22.0)"
[ "${SLUG}" = 'node-v22.22.0-openharmony-arm64' ] || die "nvm_get_download_slug produced \"${SLUG}\""
unset nvm_get_os
rm -f ./unameChecked in sh, bash, dash and zsh. It also pins that |
||
| echo "on Alpine; skipping chroot OpenHarmony checks" | ||
| else | ||
| CHROOT_UNAME_LINUX_PARAM_OPENHARMONY="${TMP_DIR}/uname_linux_param_openharmony" | ||
| CHROOT_UNAME_LINUX_PARAM_OTHER="${TMP_DIR}/uname_linux_param_other" | ||
| CHROOT_UNAME_HARMONYOS_PARAM_OPENHARMONY="${TMP_DIR}/uname_harmonyos_param_openharmony" | ||
| CHROOT_UNAME_HARMONYOS_PARAM_OTHER="${TMP_DIR}/uname_harmonyos_param_other" | ||
|
|
||
| setup_chroot "${CHROOT_UNAME_LINUX_PARAM_OPENHARMONY}" "${MOCKS_DIR}/param_openharmony" "${MOCKS_DIR}/uname_linux_aarch64" | ||
| setup_chroot "${CHROOT_UNAME_LINUX_PARAM_OTHER}" "${MOCKS_DIR}/param_other" "${MOCKS_DIR}/uname_linux_aarch64" | ||
| setup_chroot "${CHROOT_UNAME_HARMONYOS_PARAM_OPENHARMONY}" "${MOCKS_DIR}/param_openharmony" "${MOCKS_DIR}/uname_harmonyos_aarch64" | ||
| setup_chroot "${CHROOT_UNAME_HARMONYOS_PARAM_OTHER}" "${MOCKS_DIR}/param_other" "${MOCKS_DIR}/uname_harmonyos_aarch64" | ||
|
|
||
| # Linux kernel with an OpenHarmony param -> openharmony | ||
| OS_UNAME_LINUX_PARAM_OPENHARMONY=$(sudo chroot "${CHROOT_UNAME_LINUX_PARAM_OPENHARMONY}" /bin/sh -c ". ./nvm.sh && nvm_get_os") | ||
| if [ "${OS_UNAME_LINUX_PARAM_OPENHARMONY}" != "openharmony" ]; then | ||
| die "nvm_get_os produced \"${OS_UNAME_LINUX_PARAM_OPENHARMONY}\", expected \"openharmony\"" | ||
| fi | ||
|
|
||
| # Linux kernel with an unrelated param stays linux | ||
| OS_UNAME_LINUX_PARAM_OTHER=$(sudo chroot "${CHROOT_UNAME_LINUX_PARAM_OTHER}" /bin/sh -c ". ./nvm.sh && nvm_get_os") | ||
| if [ "${OS_UNAME_LINUX_PARAM_OTHER}" != "linux" ]; then | ||
| die "nvm_get_os produced \"${OS_UNAME_LINUX_PARAM_OTHER}\", expected \"linux\"" | ||
| fi | ||
|
|
||
| # HarmonyOS kernel with an OpenHarmony param -> openharmony | ||
| OS_UNAME_HARMONYOS_PARAM_OPENHARMONY=$(sudo chroot "${CHROOT_UNAME_HARMONYOS_PARAM_OPENHARMONY}" /bin/sh -c ". ./nvm.sh && nvm_get_os") | ||
| if [ "${OS_UNAME_HARMONYOS_PARAM_OPENHARMONY}" != "openharmony" ]; then | ||
| die "nvm_get_os produced \"${OS_UNAME_HARMONYOS_PARAM_OPENHARMONY}\", expected \"openharmony\"" | ||
| fi | ||
|
|
||
| # HarmonyOS kernel with an unrelated param stays empty | ||
| OS_UNAME_HARMONYOS_PARAM_OTHER=$(sudo chroot "${CHROOT_UNAME_HARMONYOS_PARAM_OTHER}" /bin/sh -c ". ./nvm.sh && nvm_get_os") | ||
| if [ "_${OS_UNAME_HARMONYOS_PARAM_OTHER}" != "_" ]; then | ||
| die "nvm_get_os produced \"${OS_UNAME_HARMONYOS_PARAM_OTHER}\", expected \"\"" | ||
| fi | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing pins the One more fixture covers it: CHROOT_UNAME_OSX_PARAM_OPENHARMONY="${TMP_DIR}/uname_osx_param_openharmony"
setup_chroot "${CHROOT_UNAME_OSX_PARAM_OPENHARMONY}" "${MOCKS_DIR}/param_openharmony" "${MOCKS_DIR}/uname_osx_amd64"
# an OS uname already identified is never re-probed
OS_UNAME_OSX_PARAM_OPENHARMONY=$(sudo chroot "${CHROOT_UNAME_OSX_PARAM_OPENHARMONY}" /bin/sh -c ". ./nvm.sh && nvm_get_os")
if [ "${OS_UNAME_OSX_PARAM_OPENHARMONY}" != "darwin" ]; then
die "nvm_get_os produced \"${OS_UNAME_OSX_PARAM_OPENHARMONY}\", expected \"darwin\""
fi |
||
| fi | ||
|
|
||
| cleanup | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this is the first unit test
Also worth knowing (not a defect, just a footnote): urchin expands the directory glob once before running, so the transient |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| if [ "$#" -eq 2 ] && [ "$1" = "get" ] && [ "$2" = "const.ohos.fullname" ]; then | ||
| echo "OpenHarmony-6.1.0.31" | ||
| fi |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| if [ "$#" -eq 2 ] && [ "$1" = "get" ] && [ "$2" = "const.ohos.fullname" ]; then | ||
| echo "SomeOtherOS-1.2.3" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth making this |
||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| if [ "_$1" = "_-m" ]; then | ||
| echo "aarch64" | ||
| else | ||
| echo "HarmonyOS localhost HongMeng Kernel 1.12.0 #1 SMP Tue Jul 14 09:40:51 UTC 2026 aarch64 Toybox" | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dieruns before the caller reachescleanup_mock_os, andcleanuphas norm -f ./uname, so a failing arm leaves an executable symlink in this directory; urchin then runs it as a test on the next pass.nvm_get_archtears down insiderun_test,nvm_get_arch alpineputsrm -f ./unameincleanup. Either is fine.