Manual, scriptable harness for driving jSMB from Samba's reference client. Designed to augment — not replace — the automated smbj-driven integration tests in src/test/java/. Gated on a Maven profile so a plain ./mvnw test and CI both skip it.
interop/
├── README.md # this file
├── run-samba-scenario.sh # wrapper that pipes a scenario to smbclient in Podman
└── scenarios/
├── smoke.txt # connect + disconnect smoke test
├── mkdir.txt # directory creation round-trip (needs M5)
└── ls.txt # forward-looking — returns NT_STATUS_NOT_SUPPORTED until M6 lands
- Podman. On macOS / Windows run
podman machine init && podman machine startonce. Linux users just need thepodmanbinary. - Java 25 + Maven to start the jSMB harness.
The first invocation of run-samba-scenario.sh builds a small local image (alpine + samba-client) tagged localhost/jsmb-smbclient:latest and caches it. Subsequent runs reuse it.
- Start the harness in a terminal (port 4445, encryption + signing +
DEBUG_ENCRYPTIONenabled, sharedatabacked by a fresh@TempDir, blocks on SIGTERM). Both the server and the wrapper default to 4445 — override with-Djsmb.port=<port>and matchingSAMBA_PORT=<port>if you hit a bind collision (e.g. macOS'supnotifypon some setups):./mvnw verify -Prun -Djsmb.config=DEBUG_ENCRYPTION
- In another terminal, run a scenario against it. The wrapper auto-selects Linux (
--network host) vs. macOS/Windows (host.containers.internal) networking:# Run a named scenario from interop/scenarios/ ./interop/run-samba-scenario.sh smoke.txt # Run an ad-hoc scenario from a heredoc (handy for quick regression probes) ./interop/run-samba-scenario.sh <<'EOF' mkdir quick-check mkdir quick-check\nested exit EOF # Or pipe from any file ./interop/run-samba-scenario.sh < /tmp/my-scenario.txt
- Inspect the output. Pair
SAMBA_DEBUG=10(Samba's max debug verbosity) with the server'sDEBUG_ENCRYPTIONlog for end-to-end cross-referencing. Every command that hits a feature jSMB hasn't implemented yet surfaces asNT_STATUS_NOT_SUPPORTED(or a more specific code) — that's how you spot regressions in milestones that are supposed to work. - Stop the server by hitting Enter (or
Ctrl-D) in the terminal running step 1.
Scenario files are plain text — one smbclient command per line. Lines starting with # (optionally after whitespace) and blank lines are stripped before being piped to smbclient, so scenarios can self-document:
# Exercises M5 (CREATE/CLOSE). `mkdir` uses FILE_DIRECTORY_FILE + FILE_CREATE internally.
mkdir foo
mkdir foo\nested
exitThe smbclient command set is documented in man smbclient; common commands are ls, cd <path>, mkdir <dir>, rmdir <dir>, get <remote> [local], put <local> [remote], rm <file>, rename <old> <new>, exit / q.
RunIT blocks on a CountDownLatch released by a JVM shutdown hook, so signalling the forked test JVM (SIGTERM / SIGINT) shuts the harness down cleanly.
# 1. Background the harness.
./mvnw -q verify -Prun > /tmp/jsmb-harness.log 2>&1 &
# 2. Wait until the server starts listening (usually ≤ 1–2 s on a warm build).
until lsof -iTCP:4445 -sTCP:LISTEN >/dev/null 2>&1; do sleep 1; done
# 3. Run a scenario and inspect the output.
./interop/run-samba-scenario.sh smoke.txt
# grep for NT_STATUS_* in stdout; expect at most NT_STATUS_INVALID_PARAMETER from
# smbclient's Kerberos pre-flight (we offer NTLM only — safe to ignore).
# 4. Optionally cross-check the server side.
grep -E 'TREE_CONNECT|CREATE|Session-' /tmp/jsmb-harness.log
# 5. Tear down. Signal the surefire-forked JVM directly (Maven's SIGTERM handler
# doesn't cascade to the forked JVM; the fork is what owns the shutdown hook).
kill -TERM "$(lsof -iTCP:4445 -sTCP:LISTEN -t)"Interactively, a terminal Ctrl-C works because it sends SIGINT to the whole process group — the forked JVM gets its own copy of the signal and its shutdown hook fires in parallel with Maven's own cleanup.
If lsof isn't available, pkill -TERM -f 'surefirebooter.*jSMB' matches the forked JVM by its booter jar path (scoped to our project so other concurrent Maven builds aren't affected).
All configurable via env vars; defaults match the run Maven profile:
| Variable | Default | Purpose |
|---|---|---|
SAMBA_PORT |
4445 |
Port the jSMB harness listens on |
SAMBA_SHARE |
data |
Share name registered by the harness |
SAMBA_USER |
DOMAIN/user%password |
smbclient -U spec |
SAMBA_DEBUG |
3 |
smbclient -d level (0–10; 10 = max) |
SAMBA_IMAGE |
localhost/jsmb-smbclient:latest |
Podman image; auto-built if absent |
Example: SAMBA_DEBUG=10 ./interop/run-samba-scenario.sh mkdir.txt runs the scenario with full Samba debug logging.
Some smbclient probes will error out until the corresponding server milestones land:
- Named-pipe RPC on
IPC$(e.g.SRVSVC): requires a pipe dispatcher (not on the roadmap). - Directory listing (
ls): requires M6 (QUERY_DIRECTORY). - Write (
put): requires M9. - Rename / delete (
rename,rm,rmdir): require M10 (SET_INFO). - Change notifications: returns
STATUS_NOT_SUPPORTEDby design.
None of these are regressions — they're the roadmap.