Documentation Index
Fetch the complete documentation index at: https://nono.sh/docs/llms.txt
Use this file to discover all available pages before exploring further.
nono includes comprehensive integration tests that verify the sandbox enforcement works correctly across different scenarios and platforms.
Running Tests
Full Test Suite
Run all integration tests with:
./tests/run_integration_tests.sh
This script:
- Builds nono in release mode
- Runs all integration test suites
- Reports results with pass/fail/skip counts
- Exits with non-zero status if any tests fail
Individual Test Suites
Run a specific test suite:
# Build first
cargo build --release
# Export binary location
export NONO_BIN="$(pwd)/target/release/nono"
# Run a specific suite
./tests/integration/test_fs_access.sh
Test Suites
The integration tests are organized into 7 focused suites:
1. Filesystem Access (test_fs_access.sh)
Tests that nono correctly enforces read/write permissions on directories and files.
| Test Category | What It Verifies |
|---|
| Directory Read | Files can be read in granted directories |
| Directory Write | Files can be written in granted directories |
| Nested Access | Permissions apply to subdirectories |
| Read-only Mode | --read flag allows reads but not writes |
| Write-only Mode | --write flag allows writes but not reads |
| Single File Access | --read-file and --write-file grant file-level permissions |
| Multiple Grants | Multiple --allow, --read, --write flags work together |
2. Sensitive Paths (test_sensitive_paths.sh)
Verifies that credential and configuration files are protected by default.
Protected paths include:
~/.ssh/ - SSH keys
~/.aws/ - AWS credentials
~/.gnupg/ - GPG keys
~/.kube/ - Kubernetes config
~/.docker/ - Docker credentials
~/.npmrc - npm auth tokens
~/.netrc - Network credentials
~/.bash_history, ~/.zsh_history - Command history
~/.bashrc, ~/.zshrc - Shell configs
These paths are blocked even if a parent directory is explicitly allowed.
3. System Paths (test_system_paths.sh)
Tests protection of system directories.
| Test Category | What It Verifies |
|---|
| System Reads | Can read from /usr/bin, /etc (needed for executables) |
| System Writes | Cannot write to system directories |
| Root Protection | Cannot write to /, /tmp/.. escapes |
| macOS Specifics | /System/Library is readable but not writable |
4. Binary Execution (test_binary_exec.sh)
Verifies that various binaries execute correctly under the sandbox.
| Category | Commands Tested |
|---|
| Basic | echo, true, false, exit codes |
| File Operations | ls, cat, head, tail, wc, grep, find, touch, mkdir |
| Shells | sh, bash, zsh, env, printenv |
| Text Processing | sort, uniq, cut, sed, awk |
| Language Runtimes | python3, node, ruby, perl, gofmt |
| Output Verification | Correct output from commands |
Language runtime tests (Python, Node, Ruby) may be skipped if the runtime is installed via Homebrew, as /opt/homebrew isn’t in the sandbox allowlist by default.
5. Network (test_network.sh)
Tests network blocking functionality.
| Test | What It Verifies |
|---|
--block-net | curl, wget, nc, ping are blocked |
| Default (allowed) | Network access works without --block-net |
| DNS Resolution | host, nslookup, dig work when network is allowed |
6. Dangerous Commands (test_commands.sh)
Verifies the current startup-only command-blocking compatibility behavior.
| Category | Commands Blocked |
|---|
| Destructive | rm, rmdir, mv |
| Permissions | chmod, chown, chgrp |
| Privilege | sudo, su, doas |
| Package Managers | pip, npm, gem, cargo install |
| System | shutdown, reboot, kill, killall |
Also tests:
--allow-command flag to permit specific blocked commands
--block-command flag to block additional commands
- documented child-process bypass behavior while the feature is deprecated in
v0.33.x
7. Edge Cases (test_edge_cases.sh)
Tests unusual scenarios and boundary conditions.
| Test Category | What It Verifies |
|---|
| Symlinks | Symlink traversal within allowed paths |
| Symlink Escapes | Symlinks to sensitive paths are blocked |
| Path Variations | Relative paths, .. references, spaces, special characters |
| Capability Queries | nono why --self for sandbox introspection, NONO_CAP_FILE env var |
| Non-existent Paths | Proper error handling for missing paths |
| Dry Run Mode | --dry-run shows sandbox info without executing |
| Mixed Permissions | Combining --read and --write directories |
Test Framework
Tests use a shared helper library (tests/lib/test_helpers.sh) providing:
# Run a test expecting success (exit 0)
expect_success "test name" command args...
# Run a test expecting failure (non-zero exit)
expect_failure "test name" command args...
# Check command output contains a string
expect_output_contains "test name" "expected string" command args...
# Skip a test with a reason
skip_test "test name" "reason"
# Platform checks
is_macos # Returns true on macOS
is_linux # Returns true on Linux
# Check if a command is available
command_exists curl
CI Pipeline
Integration tests run automatically in GitHub Actions on:
- Pull requests to
main
- Pushes to
main
The CI runs tests on both Ubuntu and macOS:
integration:
name: Integration Tests
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build release binary
run: cargo build --release
- name: Run integration tests
run: ./tests/run_integration_tests.sh
macOS Notes
-
TMPDIR: On macOS,
/var/folders (where TMPDIR points) is a system-writable path. Tests that expect write denial within TMPDIR won’t work. Write denial is instead verified via system paths (/usr/bin, /etc).
-
Homebrew runtimes: Language runtimes installed via Homebrew at
/opt/homebrew/ aren’t in the sandbox allowlist. Tests for Python, Node, Ruby gracefully skip if the runtime isn’t accessible.
Linux Notes
- Landlock ABI: Tests should work on any Landlock-enabled kernel (5.13+). Network filtering requires ABI v4+ (kernel 6.7+).
Adding New Tests
-
Create a new test file in
tests/integration/:
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
source "$SCRIPT_DIR/../lib/test_helpers.sh"
echo ""
echo -e "${BLUE}=== My New Tests ===${NC}"
verify_nono_binary
TMPDIR=$(setup_test_dir)
trap 'cleanup_test_dir "$TMPDIR"' EXIT
# Your tests here
expect_success "my test" "$NONO_BIN" run --allow "$TMPDIR" -- echo "hello"
print_summary
-
Add the suite to
tests/run_integration_tests.sh:
run_suite "$SCRIPT_DIR/integration/test_my_new.sh" "My New Tests"
-
Make the script executable:
chmod +x tests/integration/test_my_new.sh