Skip to content

Create smoke test for dlopen#1032

Open
tashabits wants to merge 1 commit intomainfrom
1004-support-dlopen-related-test-in-ci
Open

Create smoke test for dlopen#1032
tashabits wants to merge 1 commit intomainfrom
1004-support-dlopen-related-test-in-ci

Conversation

@tashabits
Copy link
Copy Markdown
Member

Add Dedicated dlopen Smoke Validation to Existing E2E Test Flow

Why

We need explicit CI signal for dynamic library loading via dlopen, while keeping the current harness architecture stable.

The existing unit harness (scripts/test_runner.py + scripts/harnesses/wasmtestreport.py) is still the main path, but dlopen positive-path validation needs a two-phase compile sequence:

  1. compile library with --compile-library
  2. compile main binary
  3. run main and verify it loaded the library successfully

What Changed

  • Added a dedicated script: scripts/dlopen_smoke_test.sh
  • Integrated one call to it in the existing make test command chain
  • Added reports/dlopen.json as a normal report artifact consumed by existing report checks
  • Kept existing harness scripts unchanged

How the dlopen Smoke Test Works

The script executes four explicit checks and logs each one in JSON:

  1. compile_library
  2. compile_main
  3. run_main
  4. verify_output_substring

For each check, the script records:

  • name
  • status (pass, fail, or skipped)
  • command
  • output (captured stdout/stderr or skip reason)

At the end it writes a summary:

  • summary.total
  • summary.passed
  • summary.failed
  • summary.skipped

Top-level status is reflected as:

  • status: pass|fail
  • number_of_failures: <failed count>

Expected Success Condition

The smoke test is considered successful when:

  • library compilation succeeds
  • main compilation succeeds
  • main execution succeeds
  • runtime output contains:

Hello, main module! (from shared library)

How It Folds into Existing make test

This is integrated directly into the current Makefile test target sequence:

  1. run unified harness (python3 ./scripts/test_runner.py --export-report report.html)
  2. run ./scripts/dlopen_smoke_test.sh
  3. continue with existing JSON scan + scripts/check_reports.py

This keeps behavior consistent with current E2E flow and avoids creating a separate CI path.

CI / Buildx Behavior

No workflow-level changes are required.

The normal E2E build command still works and now includes the new signal:

docker buildx build \
  --platform linux/amd64 \
  --file Docker/Dockerfile.e2e \
  --tag e2e:latest \
  --output type=local,dest=test-reports \
  .

Artifacts now include:

  • test-reports/reports/dlopen.json
  • existing reports (wasm.json, grates.json, report.html, etc.)

@tashabits tashabits linked an issue Apr 10, 2026 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown
Contributor

End-to-End Test Report

Test Preview

Unified Test Report

grate harness

MetricValue
Total11
Success11
Failures0
Compile Failures0
Runtime Failures0
Timeout Failures0
Missing Pair Failures0

Cases

TestStatusError TypeOutput
concurrent-request/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 2
[Cage | geteuid] PASS: 1000000 calls returned 10
[Grate|geteuid] PASS

STDERR:

interposing-calls/interpose-exec_grate.cSuccess
STDOUT:
[Grate|interpose-exec] Registering exec handler for cage 2 in grate 1 with fn ptr addr: 2
[Grate|interpose-exec] Handling function ptr: 2 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
[Grate|interpose-exec] Handling function ptr: 2 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
Exec successful, argv[1]: --execd
[Grate|interpose-exec] PASS

STDERR:

interposing-calls/interpose-exit_grate.cSuccess
STDOUT:
[Grate|interpose-exit] Registering exit handler for cage 2 in grate 1 with fn ptr addr: 2
Exiting...

[Grate|interpose-exit] PASS

STDERR:

interposing-calls/interpose-fork_grate.cSuccess
STDOUT:
[Grate|interpose-fork] Registering fork handler for cage 2 in grate 1 with fn ptr addr: 2
[Grate|interpose-fork] Handling function ptr: 2 from cage: 1
[Grate|interpose-fork] In fork_grate 1 handler for cage: 1
[Grate|interpose-fork] PASS

STDERR:

interposing-calls/interpose-mmap_grate.cSuccess
STDOUT:
[Grate|interpose-mmap] Registering mmap handler for cage 2 in grate 1 with fn ptr addr: 2
[Grate|interpose-mmap] Handling function ptr: 2 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 2 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 2 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 2 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
mmap test: PASS
[Grate|interpose-mmap] PASS

STDERR:

interposing-calls/interpose-register_grate.cSuccess
STDOUT:
[Grate|interpose-register] Registering register_handler for cage 2 in grate 1 with fn ptr addr: 3
[cage] registering 107. grateid: 2 cageid: 3
[Grate|interpose-register] Handling function ptr: 3 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|geteuid] Registering geteuid handler for cage 1 in grate 1 with fn ptr addr: 2
[Grate|interpose-register] Handling function ptr: 2 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|interpose-register] PASS

STDERR:

multi-register_grate.cSuccess
STDOUT:
[Grate|multi-register_grate] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 2
[Grate|multi-register_grate] Registering getuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|multi-register_grate] Handling function ptr: 2 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Grate|multi-register_grate] Handling function ptr: 3 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Cage | multi-register] PASS: geteuid=10, getuid=20
[Grate|multi-register] PASS

STDERR:

race-test_grate.cSuccess
STDOUT:
pass

STDERR:

simple-tests/cpdata_grate.cSuccess
STDOUT:
[Grate|open] intercepts open call: thiscage=1, arg1cage=2
[Grate|open] copied pathname: random
[cage] fd=10

STDERR:

simple-tests/diff-cage-args_grate.cSuccess
STDOUT:
[Grate|diff-cage-args] Handling function ptr: 2 from cage: 1
[Grate|diff-cage-args] In open_grate 1 handler for cage: 1
Hello world. FD=-1
[Grate|diff-cage-args] Handling function ptr: 3 from cage: 1
Goodbye world! ret=4321 buf=helloworld
[Grate|diff-cage-args] PASS

STDERR:

simple-tests/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 2
[Grate|geteuid] Handling function ptr: 2 from cage: 1
[Grate|geteuid] In geteuid_grate 1 handler for cage: 1
[Cage | geteuid] PASS: geteuid ret = 10
[Grate|geteuid] PASS

STDERR:

wasm harness

Test Report

Deterministic Tests

Summary

MetricCount
Total Test Cases197
Number of Successes197
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
File Tests
chartests.cSuccessNone0.053120s0.209399s
Success
chdir_getcwd.cSuccessNone0.051977s0.160234s
Success
chmod.cSuccessNone0.060453s0.180521s
Success
clock_gettime_highlevel.cSuccessNone0.125210s0.366554s
Success
clock_gettime_simple.cSuccessNone0.049138s0.161064s
Success
cloexec.cSuccessNone0.056714s0.240487s
Success
close.cSuccessNone0.064314s0.192706s
Success
creat_access.cSuccessNone0.056227s0.166217s
Success
doubleclose.cSuccessNone0.050155s0.148797s
Success
dup.cSuccessNone0.049033s0.167581s
Success
dup2.cSuccessNone0.054668s0.165871s
Success
dup3.cSuccessNone0.052881s0.161184s
Success
dupwrite.cSuccessNone0.056803s0.156381s
Success
etc_conf.cSuccessNone0.051646s0.160467s
Success
fchdir.cSuccessNone0.059449s0.182252s
Success
fchmod.cSuccessNone0.056301s0.176502s
Success
fcntl.cSuccessNone0.053981s0.164175s
Success
fdatasync.cSuccessNone0.053646s0.149963s
Success
filetest.cSuccessNone0.053974s0.155023s
Success
filetest1000.cSuccessNone0.064077s0.171880s
Success
flock.cSuccessNone0.063885s0.215997s
Success
fstat.cSuccessNone0.057867s0.176871s
Success
fstatfs.cSuccessNone0.053143s0.154047s
Success
fsync.cSuccessNone0.053050s0.154317s
Success
ftruncate.cSuccessNone0.058281s0.291224s
Success
getcwd.cSuccessNone0.051836s0.154699s
Success
getrandom.cSuccessNone0.054508s0.163729s
Success
ioctl.cSuccessNone0.059534s0.170171s
Success
link.cSuccessNone0.060737s0.237164s
Success
locale_test.cSuccessNone0.065323s0.644634s
Success
lseek.cSuccessNone0.061275s0.291257s
Success
mkdir_rmdir.cSuccessNone0.054663s0.160289s
Success
mkfifo_test.cSuccessNone0.061014s0.211510s
Success
mknod.cSuccessNone0.055428s0.173524s
Success
nocancel_io.cSuccessNone0.058385s0.198406s
Success
open.cSuccessNone0.051542s0.147900s
Success
openat.cSuccessNone0.050121s0.155551s
Success
path_conversion_safety.cSuccessNone0.058314s0.190430s
Success
pread_pwrite.cSuccessNone0.052825s0.168539s
Success
printf.cSuccessNone0.046170s0.138998s
Success
prlimit64.cSuccessNone0.049110s0.154885s
Success
read.cSuccessNone0.055541s0.169709s
Success
readbytes.cSuccessNone0.051713s0.149424s
Success
readdir_basic.cSuccessNone0.059171s0.189140s
Success
readlink.cSuccessNone0.057284s0.167462s
Success
readlinkat.cSuccessNone0.058077s0.177718s
Success
readv_writev_test.cSuccessNone0.058168s0.180873s
Success
rename.cSuccessNone0.059592s0.170240s
Success
sc-writev.cSuccessNone0.055050s0.164705s
Success
stat.cSuccessNone0.055594s0.161800s
Success
statfs.cSuccessNone0.050100s0.152420s
Success
sync_file_range.cSuccessNone0.054449s0.160205s
Success
timespec_time_t_compat.cSuccessNone0.054820s0.157094s
Success
truncate.cSuccessNone0.058376s0.186123s
Success
unlink.cSuccessNone0.056914s0.211914s
Success
unlinkat.cSuccessNone0.055554s0.184551s
Success
write.cSuccessNone0.048565s0.140613s
Success
writeloop.cSuccessNone0.057297s0.151241s
Success
writepartial.cSuccessNone0.054377s0.145566s
Success
writev.cSuccessNone0.057731s0.180435s
Success
Math Tests
math_link_smoke.cSuccessNone0.065346s0.155341s
Success
math_tests.cSuccessNone0.063629s0.210374s
Success
Memory Tests
brk.cSuccessNone0.053565s0.152889s
Success
fork_large_memory.cSuccessNone0.083841s0.435811s
Success
malloc.cSuccessNone0.053055s0.150931s
Success
malloc_large.cSuccessNone0.054427s0.151235s
Success
memcpy.cSuccessNone0.049859s0.143526s
Success
memory_error_test.cSuccessNone0.056596s0.190990s
Success
mmap.cSuccessNone0.047900s0.149181s
Success
mmap_aligned.cSuccessNone0.051144s0.159971s
Success
mmap_complicated.cSuccessNone0.055752s0.174015s
Success
mmap_file.cSuccessNone0.054537s0.160914s
Success
mmap_shared.cSuccessNone0.053925s0.167802s
Success
mmaptest.cSuccessNone0.051851s0.155281s
Success
mprotect.cSuccessNone0.049729s0.148249s
Success
mprotect_boundary.cSuccessNone0.050194s0.162107s
Success
mprotect_end_region.cSuccessNone0.050479s0.158534s
Success
mprotect_middle_region.cSuccessNone0.048999s0.157195s
Success
mprotect_multiple_times.cSuccessNone0.048362s0.155119s
Success
mprotect_same_value.cSuccessNone0.047980s0.153837s
Success
mprotect_spanning_regions.cSuccessNone0.049838s0.170556s
Success
sbrk.cSuccessNone0.052870s0.149013s
Success
segfault.cSuccessNone0.062548s0.196588s
Success
shm.cSuccessNone0.055404s0.172872s
Success
shmtest.cSuccessNone0.050633s0.152397s
Success
thread_malloc_sequential.cSuccessNone0.057032s0.197447s
Success
vtable.cSuccessNone0.059622s0.164774s
Success
Networking Tests
accept4.cSuccessNone0.061340s0.185068s
Success
dns_resolve_test.cSuccessNone0.055460s0.159552s
Success
dnstest.cSuccessNone0.054641s0.167733s
Success
epoll_edge_triggered.cSuccessNone0.211906s0.518522s
Success
epollcreate1.cSuccessNone0.056916s0.172152s
Success
error_handling_net.cSuccessNone0.065577s0.281862s
Success
getaddrinfo_test.cSuccessNone0.058641s0.206251s
Success
getaddrinfo_unspec.cSuccessNone0.073818s0.173801s
Success
gethostname.cSuccessNone0.054101s0.144897s
Success
getifaddrs.cSuccessNone0.056771s0.166247s
Success
getsockname.cSuccessNone0.061234s0.171620s
Success
getsockopt.cSuccessNone0.058760s0.222322s
Success
ipv6_basic.cSuccessNone0.059963s0.221467s
Success
makepipe.cSuccessNone0.049118s0.140838s
Success
nonblocking_eagain.cSuccessNone0.059647s0.223972s
Success
pipe.cSuccessNone0.058626s0.177675s
Success
pipe2.cSuccessNone0.056710s0.171752s
Success
pipeinput.cSuccessNone0.058791s0.184249s
Success
pipeinput2.cSuccessNone0.058047s0.184064s
Success
pipeonestring.cSuccessNone0.068170s0.185723s
Success
pipepong.cSuccessNone0.057012s0.187659s
Success
pipewrite.cSuccessNone0.054195s0.169416s
Success
poll.cSuccessNone0.055905s0.152671s
Success
recvfrom-sendto.cSuccessNone0.059439s0.176811s
Success
sendmsg_recvmsg_test.cSuccessNone0.057027s0.173740s
Success
serverclient.cSuccessNone0.056810s0.164460s
Success
shutdown.cSuccessNone0.058552s0.170773s
Success
shutdown_fork.cSuccessNone0.056326s0.175214s
Success
simple-select.cSuccessNone0.057436s0.184626s
Success
simple_epoll.cSuccessNone0.059462s0.172172s
Success
socket.cSuccessNone0.053952s0.155111s
Success
socket_cloexec.cSuccessNone0.055698s0.155880s
Success
socket_options_advanced.cSuccessNone0.062933s0.247644s
Success
socketepoll.cSuccessNone0.054570s0.159039s
Success
socketpair.cSuccessNone0.055098s0.166613s
Success
socketselect.cSuccessNone0.057291s0.171731s
Success
udp_send_recv.cSuccessNone0.163943s0.337352s
Success
uds-getsockname.cSuccessNone0.057931s0.161526s
Success
uds-nb-select.cSuccessNone2.062634s2.238595s
Success
uds-serverclient.cSuccessNone0.058978s0.198907s
Success
uds-socketselect.cSuccessNone0.056763s0.166470s
Success
writev_socket.cSuccessNone0.059403s0.206603s
Success
Process Tests
barrier_test.cSuccessNone0.055096s0.168574s
Success
chain_thread.cSuccessNone1.057576s1.171611s
Success
ctor_syscall_test.cSuccessNone0.046982s0.145977s
Success
cxa_atexit_test.cSuccessNone0.052701s0.146941s
Success
execve_shebang.cSuccessNone0.056907s0.166368s
Success
exit.cSuccessNone0.054052s0.200825s
Success
exit_failure.cSuccessNone0.055841s0.160555s
Success
exit_group_thread.cSuccessNone0.056595s0.169586s
Success
flockfile_test.cSuccessNone0.055879s0.185205s
Success
fork2malloc.cSuccessNone0.057058s0.166091s
Success
fork_select.cSuccessNone0.056689s0.182089s
Success
fork_simple.cSuccessNone0.054869s0.162042s
Success
fork_syscall.cSuccessNone0.061574s0.371629s
Success
fork_tls_ctype.cSuccessNone0.058576s0.190754s
Success
forkandopen.cSuccessNone0.057022s0.187235s
Success
forkdup.cSuccessNone0.060783s0.182048s
Success
forkexecuid.cSuccessNone0.056926s0.250271s
Success
forkexecv-arg.cSuccessNone0.055646s0.226136s
Success
forkexecv.cSuccessNone0.054486s0.220209s
Success
forkfiles.cSuccessNone0.058304s0.181291s
Success
forkmalloc.cSuccessNone0.065150s0.168135s
Success
forknodup.cSuccessNone0.056781s0.178209s
Success
function-ptr.cSuccessNone0.051935s0.152327s
Success
getegid_syscall.cSuccessNone0.056546s0.317777s
Success
getgid_syscall.cSuccessNone0.057164s0.376184s
Success
getpid.cSuccessNone0.050461s0.151672s
Success
getpid_syscall.cSuccessNone0.060472s0.421679s
Success
getppid.cSuccessNone0.056640s0.171413s
Success
getppid_syscall.cSuccessNone0.058534s0.269710s
Success
getuid.cSuccessNone0.056633s0.156845s
Success
getuid_syscall.cSuccessNone0.055254s0.212051s
Success
hello-arg.cSuccessNone0.048270s0.146703s
Success
hello.cSuccessNone0.047671s0.139205s
Success
longjmp.cSuccessNone0.050158s0.156709s
Success
mutex.cSuccessNone2.058085s2.179831s
Success
printf_deadlock_smoke.cSuccessNone0.064124s0.206570s
Success
printf_thread_test.cSuccessNone0.055071s0.179103s
Success
sem_forks.cSuccessNone0.058182s0.184693s
Success
setsid.cSuccessNone0.049761s0.150735s
Success
template.cSuccessNone0.056147s0.185479s
Success
test_exec_nofork.cSuccessNone0.054597s0.217888s
Success
test_unlink_open_file.cSuccessNone0.053243s0.155366s
Success
thread-test.cSuccessNone0.050771s0.153918s
Success
thread.cSuccessNone0.051035s0.154375s
Success
thread_cageid_race.cSuccessNone0.052895s0.240726s
Success
tls_test.cSuccessNone0.057576s0.184643s
Success
uname.cSuccessNone0.051240s0.148721s
Success
wait.cSuccessNone2.056069s2.168543s
Success
waitpid_anychild.cSuccessNone0.060789s0.176825s
Success
waitpid_syscall.cSuccessNone1.056543s1.216461s
Success
waitpid_wnohang.cSuccessNone0.058165s0.176044s
Success
Signal Tests
alarm.cSuccessNone7.055971s7.183284s
Success
eintr_fork_signal.cSuccessNone1.057226s1.190607s
Success
kill.cSuccessNone1.057152s1.170933s
Success
setitimer.cSuccessNone7.058417s7.190151s
Success
sigalrm.cSuccessNone2.058369s2.184369s
Success
sigchld.cSuccessNone1.059950s1.173198s
Success
signal-fork.cSuccessNone4.057069s4.171274s
Success
signal-simple.cSuccessNone0.056942s0.159405s
Success
signal_SIGCHLD.cSuccessNone0.057061s0.184344s
Success
signal_fork.cSuccessNone0.052618s0.175137s
Success
signal_int_ignored.cSuccessNone2.055997s2.171120s
Success
signal_kill_cleanup.cSuccessNone1.054748s1.166724s
Success
signal_procmask.cSuccessNone0.050529s0.162016s
Success
signal_recursive.cSuccessNone0.053582s0.172315s
Success
signal_sa_mask.cSuccessNone0.052024s0.155901s
Success
sigpipe.cSuccessNone1.058777s1.187635s
Success
sigprocmask.cSuccessNone1.054754s1.170042s
Success
Fail Tests

Summary

MetricCount
Total Test Cases4
Number of Successes4
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
Dylink Tests
dlerror.cSuccessNone0.049733s0.144807s
Success
Memory Tests
mmap-negative1.cSuccessNone0.129116s0.148041s
Success
mmap-negative2.cSuccessNone0.122821s0.154217s
Success
Signal Tests
signal_resethand.cSuccessNone1.056565s1.170971s
Success

@qianxichen233
Copy link
Copy Markdown
Contributor

a couple of more dlopen related tests are added to main, could you take a look and try to make them compatible with the pipeline as well? feel free to reorganize the file structure in dylink tests if you want (e.g. split library file and main module file into seperate directory)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support dlopen related test in CI

2 participants