nuttx-apps/system/nxinit/Kconfig
wangjianyu3 63698738a8 system/nxinit: add cmocka unit tests for parser/action/service
Add a test/ subdirectory (mirroring apps/system/uorb/test/) with
cmocka-based unit tests covering the NxInit logic most prone to
regression:

- init_parse_arguments(): plain/quoted arguments, "--" separator vs.
  "--option" long options (regression coverage for a previously fixed
  bug), argv-capacity truncation (asserting the exact folded contents
  of the last slot, not just its presence).
- init_parse_config_file()/init_parse_config_lines()/
  init_parse_config_buffer(): section routing, blank/whitespace-only
  line skipping, unknown-section rejection, over-length line rejection,
  and a line straddling two read-buffer refills, exercised through both
  the file-based and buffer-based entry points.
- Action event matching: exact match, invert (!=), fnmatch wildcards,
  and AND semantics across multiple events per action.
- Service conflict detection: duplicate service name rejection,
  override replacing an earlier duplicate, and the SERVICE_ARGS_MAX
  boundary built dynamically from CONFIG_SYSTEM_NXINIT_SERVICE_ARGS_MAX
  rather than a hardcoded value.

Test sources compile action.c/parser.c/service.c a second time into a
separate nxinit_unit_test program, gated behind new
CONFIG_SYSTEM_NXINIT_TEST (depends on TESTING_CMOCKA); the default init
program is unaffected. The CMake path builds a dedicated
nxinit_unit_test target (with test/test_nxinit.c placed first in SRCS
so nuttx_add_application() renames its main() correctly); the Make path
appends the test sources into the shared CSRCS list.

Supporting bits required to make the suite exercise the real code:

- init_parse_config_buffer() is declared in parser.h and made
  non-static so the buffer-based boundary test can call it directly,
  alongside the existing init_parse_config_file() entry point.
- CONFIG_SYSTEM_NXINIT_ACTION_EVENTS_MAX default is raised from 1 to 2
  so an action can carry more than one event ("on evA && evB"), which
  the multi-event AND-semantics test exercises; a single event slot
  made that test dead code.
- CONFIG_SYSTEM_NXINIT_TEST_STACKSIZE defaults to 8192: several parser
  test cases build multi-hundred-byte stack buffers on top of cmocka's
  own overhead, and the previous DEFAULT_TASK_STACKSIZE (2048)
  overflowed the test task's stack silently on real hardware (no crash
  dump, no watchdog reset, output just stopped) partway through the
  suite.

Testing:
Built via `make CROSSDEV=riscv-none-elf-` for
esp32p4-pico-wifi-wareshare:nsh (CONFIG_SYSTEM_NXINIT_TEST=y) and ran
nxinit_unit_test on real esp32p4-pico-wifi-wareshare hardware over
UART:

  nsh> nxinit_unit_test
  [==========] nxinit_tests: Running 18 test(s).
  ...
  [==========] nxinit_tests: 18 test(s) run.
  [  PASSED  ] 18 test(s).

nxstyle clean on all touched files.

Assisted-by: GitHubCopilot:claude-sonnet-5
Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
2026-08-28 09:33:47 -03:00

171 lines
4.3 KiB
Text

#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config SYSTEM_NXINIT
tristate "NuttX Init"
default n
depends on EXPERIMENTAL
depends on LIBC_EXECFUNCS
depends on SCHED_CHILD_STATUS
---help---
Enable NxInit(NuttX Init) component for system initialization.
The script of NxInit(init.rc) is compatible with the Android Init Language syntax.
if SYSTEM_NXINIT
comment "NXInit Basic"
config SYSTEM_NXINIT_PRIORITY
int "Thread priority"
default 100
config SYSTEM_NXINIT_STACKSIZE
int "Stack size"
default DEFAULT_TASK_STACKSIZE
config SYSTEM_NXINIT_PROGNAME
string "Program name"
default "init"
comment "NXInit Run Control(RC)"
config SYSTEM_NXINIT_RC_FILE_PATH
string "Path to RC file"
default "/etc/init.d/init.rc"
---help---
Path to the init.rc file to use for NXInit's boot logic.
config SYSTEM_NXINIT_RC_LINE_MAX
int "Max line length of RC file"
default 128
range 64 4096
---help---
Maximum line length of RC file.
More details: https://android.googlesource.com/platform/system/core/+/master/init/README.md
comment "NXInit Action"
config SYSTEM_NXINIT_ACTION_CMD_ARGS_MAX
int "Max number of command arguments"
default 8
---help---
Maximum number of command arguments.
Form:
```
on <event> [&& <event>]*
<command>
<command>
<command>
...
```
config SYSTEM_NXINIT_ACTION_WARN_SLOW
int "Slow command warning timeout"
default 50
depends on SYSTEM_NXINIT_WARN
---help---
Warning if command took more than `SYSTEM_NXINIT_ACTION_WARN_SLOW` ms.
config SYSTEM_NXINIT_ACTION_EVENTS_MAX
int "Max number of events"
default 2
range 1 64
---help---
Maximum number of event and action events.
See action.h:
```
struct action_s
{
...
struct action_event_s events[CONFIG_SYSTEM_NXINIT_ACTION_EVENTS_MAX];
...
};
```
config SYSTEM_NXINIT_FINALINIT
bool "Enable NXInit final event"
default n
---help---
Enable support to run the "final" event. Currently only "boot",
and "init" event are enabled by default, where "netinit" and
"final" are optional.
comment "NXInit Service"
config SYSTEM_NXINIT_SERVICE_ARGS_MAX
int "Max number of service arguments"
default 16
range 3 64
---help---
Maximum number of service arguments,
including "name", "pathname" and key word "service"(at least 3). Form:
```
service <name> <pathname> [ <argument> ]*
<option>
<option>
...
```
config SYSTEM_NXINIT_SERVICE_RESTART_PERIOD
int "Service restart period in ms"
default 5000
comment "NXInit Testing"
config SYSTEM_NXINIT_TEST
bool "NxInit unit tests"
default n
depends on TESTING_CMOCKA
---help---
Enable cmocka-based unit tests covering NxInit's argument/config
parser, action event matching, and service conflict detection.
Builds a separate "nxinit_unit_test" program. Under the CMake
build the test sources compile into a dedicated target and the
"init" program is unaffected; under the Make build the test
sources are appended to the shared CSRCS list, so they are also
linked into "init", enlarging it and pulling in the cmocka
dependency. Keep this disabled for production Make builds.
if SYSTEM_NXINIT_TEST
config SYSTEM_NXINIT_TEST_PRIORITY
int "Test task priority"
default 100
config SYSTEM_NXINIT_TEST_STACKSIZE
int "Test task stack size"
default 8192
---help---
Several of the parser test cases build multi-hundred-byte
buffers on the stack (e.g. lines several times
CONFIG_SYSTEM_NXINIT_RC_LINE_MAX long) on top of cmocka's own
framework overhead. On at least one real embedded target this
overflowed the default DEFAULT_TASK_STACKSIZE (2048) silently
(no crash dump, no watchdog reset, the test task just stopped
producing output), which is far harder to diagnose than an
outright test failure. 8192 has been verified to run all test
cases cleanly on that target; lower it back down only if you
have confirmed your target's stack usage stays within bounds.
endif # SYSTEM_NXINIT_TEST
comment "NXInit Log level"
config SYSTEM_NXINIT_ERR
bool "Enable error log"
default !DEFAULT_SMALL
config SYSTEM_NXINIT_WARN
bool "Enable warning log"
depends on SYSTEM_NXINIT_ERR
config SYSTEM_NXINIT_INFO
bool "Enable info log"
depends on SYSTEM_NXINIT_WARN
config SYSTEM_NXINIT_DEBUG
bool "Enable debug log"
depends on SYSTEM_NXINIT_INFO
endif