add open posix test cases on qemu and sim on CI

Signed-off-by: vela-mib <vela-mib@xiaomi.com>
This commit is contained in:
vela-mib
2024-02-20 10:54:27 +08:00
committed by Xiang Xiao
parent 306c1c0b7d
commit 8ff3b90742
10 changed files with 11684 additions and 48 deletions
@@ -16,6 +16,7 @@ CONFIG_16550_UART0_CLOCK=3686400
CONFIG_16550_UART0_IRQ=37 CONFIG_16550_UART0_IRQ=37
CONFIG_16550_UART0_SERIAL_CONSOLE=y CONFIG_16550_UART0_SERIAL_CONSOLE=y
CONFIG_16550_UART=y CONFIG_16550_UART=y
CONFIG_ALLOW_MIT_COMPONENTS=y
CONFIG_ARCH="risc-v" CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="rv-virt" CONFIG_ARCH_BOARD="rv-virt"
CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y CONFIG_ARCH_BOARD_QEMU_RV_VIRT=y
@@ -27,33 +28,58 @@ CONFIG_ARCH_CHIP_QEMU_RV_ISA_C=y
CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y CONFIG_ARCH_CHIP_QEMU_RV_ISA_M=y
CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y CONFIG_ARCH_RISCV=y
CONFIG_ARCH_SETJMP_H=y
CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARDCTL_ROMDISK=y
CONFIG_BOARD_LOOPSPERMSEC=6366 CONFIG_BOARD_LOOPSPERMSEC=6366
CONFIG_BUILTIN=y CONFIG_BUILTIN=y
CONFIG_CANCELLATION_POINTS=y
CONFIG_DEBUG_ASSERTIONS=y CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEV_ZERO=y CONFIG_DEV_ZERO=y
CONFIG_ELF=y CONFIG_ELF=y
CONFIG_ETC_ROMFS=y
CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_HELLOXX=y CONFIG_EXAMPLES_HELLOXX=y
CONFIG_EXAMPLES_PIPE=y CONFIG_EXAMPLES_PIPE=y
CONFIG_EXAMPLES_POPEN=y CONFIG_EXAMPLES_POPEN=y
CONFIG_EXAMPLES_ROMFS=y
CONFIG_EXAMPLES_USRSOCKTEST=y CONFIG_EXAMPLES_USRSOCKTEST=y
CONFIG_FAT_LFN=y
CONFIG_FS_AIO=y
CONFIG_FS_FAT=y
CONFIG_FS_HOSTFS=y CONFIG_FS_HOSTFS=y
CONFIG_FS_NAMED_SEMAPHORES=y
CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS=y
CONFIG_FS_ROMFS=y
CONFIG_FS_SHMFS=y
CONFIG_FS_TMPFS=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y CONFIG_INTELHEX_BINARY=y
CONFIG_IOB_NBUFFERS=128
CONFIG_IOB_NCHAINS=4
CONFIG_LIBCXX=y
CONFIG_LIBCXXABI=y
CONFIG_LIBC_ENVPATH=y CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_LOCALE_CATALOG=y
CONFIG_LIBC_LOCALTIME=y
CONFIG_LIBC_MAX_EXITFUNS=32
CONFIG_LIBC_MEMFD_ERROR=y
CONFIG_LIBC_PERROR_STDOUT=y CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y CONFIG_LIBC_STRERROR=y
CONFIG_LIBM=y
CONFIG_MM_IOB=y
CONFIG_MQ_MAXMSGSIZE=128
CONFIG_NET=y CONFIG_NET=y
CONFIG_NETDEV_LATEINIT=y CONFIG_NETDEV_LATEINIT=y
CONFIG_NETUTILS_NETINIT=y CONFIG_NETUTILS_NETINIT=y
CONFIG_NET_ICMP=y
CONFIG_NET_LOCAL=y
CONFIG_NET_USRSOCK=y CONFIG_NET_USRSOCK=y
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
CONFIG_NSH_ARCHINIT=y CONFIG_NSH_ARCHINIT=y
@@ -63,21 +89,41 @@ CONFIG_NSH_READLINE=y
CONFIG_PATH_INITIAL="/system/bin" CONFIG_PATH_INITIAL="/system/bin"
CONFIG_PREALLOC_TIMERS=0 CONFIG_PREALLOC_TIMERS=0
CONFIG_PSEUDOFS_SOFTLINKS=y CONFIG_PSEUDOFS_SOFTLINKS=y
CONFIG_PTHREAD_CLEANUP_STACKSIZE=4
CONFIG_PTHREAD_SPINLOCKS=y
CONFIG_PTHREAD_STACK_DEFAULT=8192
CONFIG_PTHREAD_STACK_MIN=8192
CONFIG_RAM_SIZE=33554432 CONFIG_RAM_SIZE=33554432
CONFIG_RAM_START=0x80000000 CONFIG_RAM_START=0x80000000
CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RISCV_SEMIHOSTING_HOSTFS=y CONFIG_RISCV_SEMIHOSTING_HOSTFS=y
CONFIG_RR_INTERVAL=200 CONFIG_RR_INTERVAL=10
CONFIG_SCHED_CHILD_STATUS=y
CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_HPWORK=y CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_LPNTHREADS=1
CONFIG_SCHED_LPWORK=y CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_USER_IDENTITY=y
CONFIG_SERIAL_UART_ARCH_MMIO=y CONFIG_SERIAL_UART_ARCH_MMIO=y
CONFIG_SIG_DEFAULT=y
CONFIG_SIG_EVTHREAD=y
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=12 CONFIG_START_MONTH=12
CONFIG_START_YEAR=2021 CONFIG_START_YEAR=2021
CONFIG_SYMTAB_ORDEREDBYNAME=y CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_POPEN=y CONFIG_SYSTEM_POPEN=y
CONFIG_TESTING_CMOCKA=y
CONFIG_TESTING_CXXTEST=y
CONFIG_TESTING_FMEMOPEN_TEST=y
CONFIG_TESTING_FOPENCOOKIE_TEST=y
CONFIG_TESTING_FSTEST=y
CONFIG_TESTING_GETPRIME=y CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_LTP=y
CONFIG_TESTING_MM=y CONFIG_TESTING_MM=y
CONFIG_TESTING_OPEN_MEMSTREAM=y
CONFIG_TESTING_OSTEST=y CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_SCANFTEST=y
CONFIG_TLS_NELEM=8
CONFIG_USEC_PER_TICK=1000 CONFIG_USEC_PER_TICK=1000
+39 -3
View File
@@ -8,6 +8,7 @@
# CONFIG_NET_ARP is not set # CONFIG_NET_ARP is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set # CONFIG_NSH_CMDOPT_HEXDUMP is not set
# CONFIG_NSH_NETINIT is not set # CONFIG_NSH_NETINIT is not set
CONFIG_ALLOW_MIT_COMPONENTS=y
CONFIG_ALLSYMS=y CONFIG_ALLSYMS=y
CONFIG_ARCH="sim" CONFIG_ARCH="sim"
CONFIG_ARCH_BOARD="sim" CONFIG_ARCH_BOARD="sim"
@@ -17,9 +18,11 @@ CONFIG_ARCH_MATH_H=y
CONFIG_ARCH_SIM=y CONFIG_ARCH_SIM=y
CONFIG_BOARDCTL_APP_SYMTAB=y CONFIG_BOARDCTL_APP_SYMTAB=y
CONFIG_BOARDCTL_POWEROFF=y CONFIG_BOARDCTL_POWEROFF=y
CONFIG_BOARDCTL_ROMDISK=y
CONFIG_BOARD_LOOPSPERMSEC=0 CONFIG_BOARD_LOOPSPERMSEC=0
CONFIG_BOOT_RUNFROMEXTSRAM=y CONFIG_BOOT_RUNFROMEXTSRAM=y
CONFIG_BUILTIN=y CONFIG_BUILTIN=y
CONFIG_CANCELLATION_POINTS=y
CONFIG_DEBUG_ASSERTIONS=y CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_SYMBOLS=y CONFIG_DEBUG_SYMBOLS=y
@@ -28,52 +31,82 @@ CONFIG_DEV_LOOP=y
CONFIG_DEV_ZERO=y CONFIG_DEV_ZERO=y
CONFIG_ETC_FATDEVNO=2 CONFIG_ETC_FATDEVNO=2
CONFIG_ETC_ROMFS=y CONFIG_ETC_ROMFS=y
CONFIG_ETC_ROMFSDEVNO=1
CONFIG_EXAMPLES_GPIO=y CONFIG_EXAMPLES_GPIO=y
CONFIG_EXAMPLES_HELLO=y CONFIG_EXAMPLES_HELLO=y
CONFIG_EXAMPLES_HELLOXX=y CONFIG_EXAMPLES_HELLOXX=y
CONFIG_EXAMPLES_PIPE=y CONFIG_EXAMPLES_PIPE=y
CONFIG_EXAMPLES_POPEN=y CONFIG_EXAMPLES_POPEN=y
CONFIG_EXAMPLES_ROMFS=y
CONFIG_EXAMPLES_USRSOCKTEST=y CONFIG_EXAMPLES_USRSOCKTEST=y
CONFIG_FAT_LCNAMES=y CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y CONFIG_FAT_LFN=y
CONFIG_FRAME_POINTER=y
CONFIG_FSUTILS_PASSWD=y CONFIG_FSUTILS_PASSWD=y
CONFIG_FSUTILS_PASSWD_READONLY=y CONFIG_FSUTILS_PASSWD_READONLY=y
CONFIG_FS_AIO=y
CONFIG_FS_BINFS=y CONFIG_FS_BINFS=y
CONFIG_FS_FAT=y CONFIG_FS_FAT=y
CONFIG_FS_NAMED_SEMAPHORES=y
CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS=y
CONFIG_FS_RAMMAP=y CONFIG_FS_RAMMAP=y
CONFIG_FS_ROMFS=y CONFIG_FS_ROMFS=y
CONFIG_FS_SHMFS=y
CONFIG_FS_TMPFS=y
CONFIG_GPIO_LOWER_HALF=y CONFIG_GPIO_LOWER_HALF=y
CONFIG_HAVE_CXX=y CONFIG_HAVE_CXX=y
CONFIG_IDLETHREAD_STACKSIZE=4096 CONFIG_IDLETHREAD_STACKSIZE=4096
CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_IOB_NBUFFERS=128
CONFIG_IOB_NCHAINS=4
CONFIG_IOEXPANDER=y CONFIG_IOEXPANDER=y
CONFIG_IOEXPANDER_DUMMY=y CONFIG_IOEXPANDER_DUMMY=y
CONFIG_LIBCXX=y CONFIG_LIBCXX=y
CONFIG_LIBC_DLFCN=y
CONFIG_LIBC_ENVPATH=y CONFIG_LIBC_ENVPATH=y
CONFIG_LIBC_EXECFUNCS=y CONFIG_LIBC_EXECFUNCS=y
CONFIG_LIBC_FLOATINGPOINT=y CONFIG_LIBC_FLOATINGPOINT=y
CONFIG_LIBC_LOCALE_CATALOG=y CONFIG_LIBC_LOCALE_CATALOG=y
CONFIG_LIBC_LOCALE_GETTEXT=y CONFIG_LIBC_LOCALE_GETTEXT=y
CONFIG_LIBC_MAX_EXITFUNS=1 CONFIG_LIBC_LOCALTIME=y
CONFIG_LIBC_MAX_EXITFUNS=32
CONFIG_LIBC_MEMFD_ERROR=y
CONFIG_LIBC_NETDB=y
CONFIG_LIBC_NUMBERED_ARGS=y CONFIG_LIBC_NUMBERED_ARGS=y
CONFIG_LIBC_SCANSET=y CONFIG_LIBC_SCANSET=y
CONFIG_LIBUV=y
CONFIG_LIBUV_UTILS_TEST=y
CONFIG_MM_IOB=y
CONFIG_MQ_MAXMSGSIZE=128
CONFIG_NET=y CONFIG_NET=y
CONFIG_NETDEV_HPWORK_THREAD=y
CONFIG_NETDEV_LATEINIT=y
CONFIG_NET_ICMP=y
CONFIG_NET_LOCAL=y
CONFIG_NET_USRSOCK=y CONFIG_NET_USRSOCK=y
CONFIG_NSH_ARCHINIT=y CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILE_APPS=y
CONFIG_NSH_MOTD=y CONFIG_NSH_MOTD=y
CONFIG_NSH_MOTD_STRING="MOTD: username=admin password=Administrator" CONFIG_NSH_MOTD_STRING="MOTD: username=admin password=Administrator"
CONFIG_NSH_READLINE=y CONFIG_NSH_READLINE=y
CONFIG_PATH_INITIAL="/bin" CONFIG_PATH_INITIAL="/bin"
CONFIG_PSEUDOFS_ATTRIBUTES=y CONFIG_PSEUDOFS_ATTRIBUTES=y
CONFIG_PSEUDOFS_SOFTLINKS=y CONFIG_PSEUDOFS_SOFTLINKS=y
CONFIG_PTHREAD_CLEANUP_STACKSIZE=4
CONFIG_PTHREAD_SPINLOCKS=y
CONFIG_PTHREAD_STACK_DEFAULT=8192
CONFIG_PTHREAD_STACK_MIN=8192
CONFIG_READLINE_TABCOMPLETION=y CONFIG_READLINE_TABCOMPLETION=y
CONFIG_RR_INTERVAL=10
CONFIG_SCHED_BACKTRACE=y CONFIG_SCHED_BACKTRACE=y
CONFIG_SCHED_CHILD_STATUS=y
CONFIG_SCHED_HAVE_PARENT=y CONFIG_SCHED_HAVE_PARENT=y
CONFIG_SCHED_LPNTHREADS=1
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_USER_IDENTITY=y
CONFIG_SIG_DEFAULT=y
CONFIG_SIG_EVTHREAD=y
CONFIG_SIM_WALLTIME_SIGNAL=y CONFIG_SIM_WALLTIME_SIGNAL=y
CONFIG_SPINLOCK=y
CONFIG_START_MONTH=6 CONFIG_START_MONTH=6
CONFIG_START_YEAR=2008 CONFIG_START_YEAR=2008
CONFIG_SYSTEM_DUMPSTACK=y CONFIG_SYSTEM_DUMPSTACK=y
@@ -85,8 +118,11 @@ CONFIG_TESTING_FOPENCOOKIE_TEST=y
CONFIG_TESTING_FSTEST=y CONFIG_TESTING_FSTEST=y
CONFIG_TESTING_FSTEST_MOUNTPT="/tmp" CONFIG_TESTING_FSTEST_MOUNTPT="/tmp"
CONFIG_TESTING_GETPRIME=y CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_LTP=y
CONFIG_TESTING_MM=y CONFIG_TESTING_MM=y
CONFIG_TESTING_OPEN_MEMSTREAM=y CONFIG_TESTING_OPEN_MEMSTREAM=y
CONFIG_TESTING_OSTEST=y CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_SCANFTEST=y CONFIG_TESTING_SCANFTEST=y
CONFIG_TESTING_SCANFTEST_FNAME="/tmp/test.txt" CONFIG_TESTING_SCANFTEST_FNAME="/tmp/test.txt"
CONFIG_TLS_NELEM=16
CONFIG_TLS_TASK_NELEM=8
+8
View File
@@ -20,8 +20,13 @@ else
if [ "${config:$((-2))}" == "64" ]; then if [ "${config:$((-2))}" == "64" ]; then
BOARD="${BOARD}64" BOARD="${BOARD}64"
fi fi
if [ "$BOARD" == "rv-virt" ]; then
target="qemu"
mark="qemu or rv_virt"
else
target="qemu" target="qemu"
mark=$target mark=$target
fi
fi fi
core=$target core=$target
@@ -35,6 +40,9 @@ ret="$?"
find ${nuttx}/tools/ci/testrun -name '__pycache__' |xargs rm -rf find ${nuttx}/tools/ci/testrun -name '__pycache__' |xargs rm -rf
find ${nuttx}/tools/ci/testrun -name '.pytest_cache' |xargs rm -rf find ${nuttx}/tools/ci/testrun -name '.pytest_cache' |xargs rm -rf
rm -rf ${logs} rm -rf ${logs}
rm -rf ${nuttx}/../apps/testing/ltp/ltp/
rm -f ${nuttx}/../apps/testing/cmocka/cmocka.zip
echo $ret echo $ret
exit $ret exit $ret
+1
View File
@@ -14,4 +14,5 @@ markers =
common : 'marks tests as common' common : 'marks tests as common'
sim : 'marks tests as simulator' sim : 'marks tests as simulator'
qemu : 'marks tests as qemu' qemu : 'marks tests as qemu'
rv_virt : 'marks tests as rv-virt'
disable_autouse : 'disable autouse' disable_autouse : 'disable autouse'
@@ -16,7 +16,7 @@ def test_helloxx(p):
def test_pipe(p): def test_pipe(p):
ret = p.sendCommand("pipe", "redirect_reader: Returning success", 60) ret = p.sendCommand("pipe", "redirect_reader: Returning success", timeout=60)
assert ret == 0 assert ret == 0
@@ -26,5 +26,5 @@ def test_popen(p):
def test_usrsocktest(p): def test_usrsocktest(p):
ret = p.sendCommand("usrsocktest", "FAILED:0", 60) ret = p.sendCommand("usrsocktest", "FAILED:0", timeout=60)
assert ret == 0 assert ret == 0
@@ -0,0 +1,2 @@
#!/usr/bin/python3
# encoding: utf-8
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -7,14 +7,14 @@ do_not_support = ["sabre-6quad", "rv-virt", "rv-virt64", "esp32c3-devkit", "bl60
def test_ostest(p): def test_ostest(p):
ret = p.sendCommand("ostest", "Exiting with status 0", 300) ret = p.sendCommand("ostest", "Exiting with status 0", timeout=300)
assert ret == 0 assert ret == 0
def test_mm(p): def test_mm(p):
if p.board in do_not_support: if p.board in do_not_support:
pytest.skip("unsupported at {}".format(p.board)) pytest.skip("unsupported at {}".format(p.board))
ret = p.sendCommand("mm", "TEST COMPLETE", 120) ret = p.sendCommand("mm", "TEST COMPLETE", timeout=120)
assert ret == 0 assert ret == 0
@@ -56,7 +56,7 @@ def test_fs_test(p):
pytest.skip("unsupported at {}".format(p.board)) pytest.skip("unsupported at {}".format(p.board))
fstest_dir = "{}/{}_fstest".format(p.fs, p.core) fstest_dir = "{}/{}_fstest".format(p.fs, p.core)
p.sendCommand("mkdir %s" % fstest_dir) p.sendCommand("mkdir %s" % fstest_dir)
ret = p.sendCommand("fstest -n 10 -m %s" % fstest_dir, "FAILED: 0", 2000) ret = p.sendCommand("fstest -n 10 -m %s" % fstest_dir, "FAILED: 0", timeout=2000)
p.sendCommand("ls %s" % fstest_dir) p.sendCommand("ls %s" % fstest_dir)
p.sendCommand("rmdir %s" % fstest_dir) p.sendCommand("rmdir %s" % fstest_dir)
assert ret == 0 assert ret == 0
@@ -67,6 +67,6 @@ def test_psram_test(p):
if p.board in do_not_support: if p.board in do_not_support:
pytest.skip("unsupported at {}".format(p.board)) pytest.skip("unsupported at {}".format(p.board))
if p.sendCommand("ls /", "tmp/") == 0: if p.sendCommand("ls /", "tmp/") == 0:
ret = p.sendCommand("fstest -n 10 -m /tmp", "Final memory usage", 500) ret = p.sendCommand("fstest -n 10 -m /tmp", "Final memory usage", timeout=500)
p.sendCommand("ls /tmp") p.sendCommand("ls /tmp")
assert ret == 0 assert ret == 0
+155 -31
View File
@@ -4,13 +4,43 @@ import os
import re import re
import subprocess import subprocess
import time import time
from enum import Enum
import pexpect import pexpect
import pexpect.fdpexpect import pexpect.fdpexpect
import pexpect.spawnbase
import serial import serial
rootPath = os.path.dirname(os.path.abspath(__file__)) rootPath = os.path.dirname(os.path.abspath(__file__))
tmp_read_nonblocking = pexpect.spawnbase.SpawnBase.read_nonblocking
def enhanced_read_nonblocking(self, size=1, timeout=None):
return re.sub(
r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]",
"",
tmp_read_nonblocking(self, size, timeout).decode(errors="ignore"),
).encode()
pexpect.spawnbase.SpawnBase.read_nonblocking = enhanced_read_nonblocking
class StatusCodeEnum(Enum):
NORMAL = (0, "Normal")
TIMEOUT_ERR = (-1, "Timeout")
EOF_ERR = (-2, "EOF")
CRASH_ERR = (-3, "Crash happened")
BUSYLOOP_ERR = (-4, "Busy loop happened")
UNKNOWN_ERR = (-5, "Unknown")
@staticmethod
def get_enum_msg_by_code(status_code):
for status in StatusCodeEnum:
if status.value[0] == status_code:
return status.value[1]
class connectNuttx(object): class connectNuttx(object):
def __init__( def __init__(
@@ -40,6 +70,7 @@ class connectNuttx(object):
self.target = target self.target = target
self.enter = "\r" self.enter = "\r"
self.debug_flag = 0 self.debug_flag = 0
self.format_str_len = 105
# get PROMPT value and rate value # get PROMPT value and rate value
self.PROMPT = getConfigValue( self.PROMPT = getConfigValue(
self.path, self.board, core=self.core, flag="NSH_PROMPT_STRING" self.path, self.board, core=self.core, flag="NSH_PROMPT_STRING"
@@ -107,38 +138,130 @@ class connectNuttx(object):
self.process.send(byte) self.process.send(byte)
time.sleep(1) time.sleep(1)
self.process.send(byte) self.process.send(byte)
time.sleep(1)
self.process.sendline("\n") def print_format_str(self, string, type="text"):
ret = self.process.expect_exact(expect) str_prefix = "+"
return ret str_suffix = "+"
if type == "head":
rest_char_len = self.format_str_len - 2 - len(string)
half_len = int(rest_char_len / 2)
print(
str_prefix
+ "-" * half_len
+ string
+ "-" * (rest_char_len - half_len)
+ str_suffix
)
elif type == "tail":
rest_char_len = self.format_str_len - 2
print(str_prefix + "-" * rest_char_len + str_suffix)
elif type == "text":
str_prefix = "| "
str_suffix = " |"
rest_char_len = (
self.format_str_len - len(str_prefix) - len(str_suffix) - len(string)
)
print(
str_prefix
+ string
+ " " * (1 if rest_char_len < 1 else rest_char_len)
+ str_suffix
)
else:
print(string)
def clean_buffer(self):
i = -1
while True:
if (
(
self.process.before is not None
and self.process.before.decode(errors="ignore")
.replace("\r", "")
.replace("\n", "")
!= ""
)
or (
self.process.after is not None
and self.process.after != pexpect.TIMEOUT
and self.process.after.decode(errors="ignore")
.replace("\r", "")
.replace("\n", "")
!= ""
)
or i == 0
):
i = self.process.expect(
[re.compile(b".+"), pexpect.TIMEOUT, pexpect.EOF], timeout=0.1
)
else:
while True:
try:
self.process.read_nonblocking(
size=self.process.maxread, timeout=0.1
)
except Exception:
break
self.process.before = b""
self.process.after = b""
break
# send command to nsh # send command to nsh
def sendCommand(self, cmd, expect="", timeout=10, flag=""): def sendCommand(self, cmd, *argc, **argv):
expect = []
timeout = 10
ret = StatusCodeEnum.NORMAL.value[0]
length = len(argc)
if length == 0:
expect.append(self.PROMPT)
else:
for i in argc:
expect.append(i)
length = len(argv)
if length != 0:
for key, value in argv.items():
if key == "timeout":
timeout = value
if self.method != "minicom": if self.method != "minicom":
time.sleep(0.5) time.sleep(0.5)
if not expect: if self.target == "qemu":
expect = self.PROMPT self.clean_buffer()
self.process.buffer = b""
self.process.sendline(cmd) self.process.sendline(cmd)
try:
ret = self.process.expect(expect, timeout=timeout)
except pexpect.TIMEOUT:
print("Debug: TIMEOUT '%s' exist and run next test case" % cmd)
ret = -1
except pexpect.EOF:
print("Debug: EOF raise exception")
ret = -2
finally:
if self.debug_flag:
self.debug(cmd, ret)
self.process.buffer = b""
self.process.sendline("\n")
if flag:
is_newline = self.process.expect_exact(flag, timeout=timeout)
else: else:
is_newline = self.process.expect_exact(self.PROMPT, timeout=timeout) self.clean_buffer()
if self.debug_flag: self.process.sendline(cmd)
self.debug("NEWLINE", is_newline) time.sleep(0.1)
self.process.send("\r\n\r\n")
try:
for i in expect:
ret = self.process.expect(i, timeout=timeout)
except Exception as e:
self.print_format_str(" Catch Exception ", type="head")
if isinstance(e, pexpect.TIMEOUT):
ret = StatusCodeEnum.TIMEOUT_ERR.value[0]
elif isinstance(e, pexpect.EOF):
ret = StatusCodeEnum.EOF_ERR.value[0]
self.print_format_str(f"An pexpect.EOF error occurred: {str(e)}")
else:
ret = StatusCodeEnum.UNKNOWN_ERR.value[0]
self.print_format_str(f"An unexpected error occurred: {str(e)}")
self.print_format_str(" Result ", type="head")
self.print_format_str(f"Command : '{cmd}'")
self.print_format_str(f"Expect value: {str(expect)}")
self.print_format_str(f"Timeout : {timeout}s")
self.print_format_str(
f"Test result : {StatusCodeEnum.get_enum_msg_by_code(ret)}"
)
self.print_format_str("", type="tail")
finally:
self.debug(cmd, ret)
if self.method != "minicom": if self.method != "minicom":
time.sleep(0.5) time.sleep(0.5)
return ret return ret
@@ -151,14 +274,15 @@ class connectNuttx(object):
self.process.expect_exact(self.PROMPT) self.process.expect_exact(self.PROMPT)
def debug(self, cmd, ret): def debug(self, cmd, ret):
if self.debug_flag:
print("********************* DEBUG START ********************") print("********************* DEBUG START ********************")
if cmd == "\n": if cmd == "\n":
cmd = r"\n" cmd = r"\n"
print("cmd: %s\n" % cmd) print("cmd: {}".format(cmd))
print("ret: %s\n" % str(ret)) print("ret: {}".format(ret))
print("before: %s\n" % repr(self.process.before)) print("before: {}".format(self.process.before.decode(errors="ignore")))
print("after: %s\n" % repr(self.process.after)) print("after: {}".format(self.process.after.decode(errors="ignore")))
print("buffer: %s\n" % repr(self.process.buffer)) print("buffer: {}".format(self.process.buffer.decode(errors="ignore")))
print("********************** DEBUG END **********************") print("********************** DEBUG END **********************")
def cleanup(self): def cleanup(self):
+235
View File
@@ -0,0 +1,235 @@
import re
from datetime import datetime
from typing import Dict, List
"""
cmocka.json
"""
Passed = "Passed"
Failed = "Failed"
Unexecuted = "Unexecuted"
class CaseInfo:
def __init__(self, test_suite_name, test_case_name, status, log=None):
self.test_suite_name = test_suite_name
# case namee.g. "TestNuttxMm01"
self.test_case_name = test_case_name
# result: Passed or Failed
self.status = status
# log
self.log: List = [""] if log is None else log
class SuiteInfo:
def __init__(self, test_suite_name):
# suite name, e.g. "NuttxMmTestSuites"
self.test_suite_name = test_suite_name
# all test cases in the current test suite
self.test_cases: Dict[str, CaseInfo] = dict()
# number of cases passed in the current test suites
self.passed_count = 0
# number of cases failed in the current test suites
self.failed_count = 0
# case run count
self.run_count = 0
# unexecuted count
self.unexecuted_count = 0
# number of cases in the current test suites
self.cases_count = 0
# suite run flag
self.is_suite_run = False
class CmockaSummary:
def __init__(self, duration=0):
# number of all test suites
self.total_suites_count = 0
# all test cases number
self.total_cases_count = 0
# number of all passed cases
self.total_passed_count = 0
# number of all failed cases
self.total_failed_count = 0
# number of all unknown cases
self.total_unexecuted_count = 0
# duration
self.duration = duration
class CmockaSingleCoreRecord:
def __init__(self, lines, core="", board="", log="", duration=0):
# create time
self.create_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# core
self.core = "" if core is None else core
# board
self.board = "" if board is None else board
# cmocka info
self.test_suites: Dict[str, SuiteInfo] = dict()
# summary
self.summary = CmockaSummary(duration)
# log path
self.log = "" if log is None else log
# bad_case
self.bad_case_tip = ""
suite_pattern = r"\] (?P<test_suite_name>[a-zA-Z]*TestSuites)"
case_pattern = r"\]\s+(?P<test_case_name>TestNuttx\w+)"
lines_iter = iter(lines)
current_suite = None
while True:
try:
line = next(lines_iter)
if (suite_match := re.search(suite_pattern, line)) is not None:
current_suite = suite_match.group("test_suite_name")
elif (
current_suite is not None
and (case_match := re.search(case_pattern, line)) is not None
):
current_case = case_match.group("test_case_name")
self.append(CaseInfo(current_suite, current_case, Unexecuted))
except StopIteration:
break
def append(self, object: CaseInfo):
suite: SuiteInfo = self.test_suites.get(object.test_suite_name)
if suite is None:
suite = SuiteInfo(object.test_suite_name)
self.test_suites.update({object.test_suite_name: suite})
suite.test_cases.update({object.test_case_name: object})
passed_count = 0
failed_count = 0
unexecuted_count = 0
test_case: CaseInfo
for test_case in suite.test_cases.values():
if test_case.status == Passed:
passed_count += 1
elif test_case.status == Failed:
failed_count += 1
else:
unexecuted_count += 1
suite.passed_count = passed_count
suite.failed_count = failed_count
suite.unexecuted_count = unexecuted_count
suite.run_count = passed_count + failed_count
suite.cases_count = passed_count + failed_count + unexecuted_count
if passed_count + failed_count != 0:
suite.is_suite_run = True
total_passed_count = 0
total_failed_count = 0
total_unexecuted_count = 0
total_cases_count = 0
suite: SuiteInfo
for suite in self.test_suites.values():
total_passed_count += suite.passed_count
total_failed_count += suite.failed_count
total_unexecuted_count += suite.unexecuted_count
total_cases_count += suite.cases_count
self.summary.total_passed_count = total_passed_count
self.summary.total_failed_count = total_failed_count
self.summary.total_unexecuted_count = total_unexecuted_count
self.summary.total_cases_count = total_cases_count
self.summary.total_suites_count = len(self.test_suites)
def process(self, lines, err_code):
# regular expression
suite_start_pattern = r"\] (?P<test_suite_name>[a-zA-Z]*TestSuites): Running (?P<cases_count>\d+) test\(s\)"
case_run_pattern = r"\[\s+RUN\s+\] (?P<test_case_name>TestNuttx\w+)"
case_pass_pattern = r"\[\s+OK\s+\] (?P<test_case_name>TestNuttx\w+)"
case_fail_pattern = r"\[\s+FAILED\s+\] (?P<test_case_name>TestNuttx\w+)"
lines_iter = iter(lines)
line = next(lines_iter)
while True:
try:
interrupt_flag = False
# matching new test suites
if (
suite_start_match := re.search(suite_start_pattern, line)
) is not None:
test_suite_name = suite_start_match.group("test_suite_name")
cases_count = int(suite_start_match.group("cases_count"))
suite_end_pattern = r"{}: {} test(s) run.".format(
test_suite_name, cases_count
)
line = next(lines_iter)
while True:
if (
case_run_match := re.search(case_run_pattern, line)
) is not None:
test_case_name = case_run_match.group("test_case_name")
log = [line]
while True:
try:
line = next(lines_iter)
log.append(line)
except StopIteration:
self.append(
CaseInfo(
test_suite_name, test_case_name, Failed, log
)
)
if err_code == -3:
self.bad_case_tip = f"This case was not executed, \
because crash occurred after running '{test_case_name}'."
elif err_code == -4:
self.bad_case_tip = f"This case was not executed, \
because no response for a long time after running '{test_case_name}'."
elif err_code == -1:
self.bad_case_tip = f"This case was not executed, \
because the maximum waiting time has been exceeded \
while running '{test_case_name}'."
else:
self.bad_case_tip = "This case was not executed due to unknown reasons."
raise StopIteration
if re.search(case_pass_pattern, line) is not None:
self.append(
CaseInfo(
test_suite_name, test_case_name, Passed, log
)
)
break
elif re.search(case_fail_pattern, line) is not None:
self.append(
CaseInfo(
test_suite_name, test_case_name, Failed, log
)
)
break
elif re.search(suite_start_pattern, line) is not None:
self.append(
CaseInfo(
test_suite_name, test_case_name, Failed, log
)
)
interrupt_flag = True
break
elif suite_end_pattern in line:
break
if interrupt_flag:
break
line = next(lines_iter)
if interrupt_flag:
continue
line = next(lines_iter)
except StopIteration:
break