Skip to content

Development Guide

Ryan edited this page Mar 28, 2026 · 2 revisions

Development Guide

How to set up a development environment, run the test suite, and verify changes.

Prerequisites

Tool Version Purpose Install
bash 4.4+ Script execution Pre-installed
socat any Runtime dependency sudo apt-get install -y socat
BATS 1.5+ Test framework See below
ShellCheck 0.8+ Static analysis sudo apt-get install -y shellcheck
GNU Make 3.81+ Build automation Pre-installed
Git 2.0+ Version control Pre-installed

Installing BATS

Install from source for the latest version (apt's version is outdated):

git clone --depth 1 https://github.com/bats-core/bats-core.git /tmp/bats-core
sudo /tmp/bats-core/install.sh /usr/local
bats --version

Verify All Prerequisites

make check-deps

Setting Up

git clone https://github.com/Sandler73/Socat-Network-Operations-Manager.git
cd Socat-Network-Operations-Manager
make check-deps
make test

You should see "✓ All tests passed" with 220 tests.

Running Tests

Full Suite

make test

Runs ShellCheck lint, then unit tests, then integration tests. All 220 tests must pass.

Individual Groups

make lint             # ShellCheck only
make test-unit        # Unit tests (~2 seconds, no stubs)
make test-integration # Integration tests (~10 seconds, uses stubs)

Single File or Test

bats tests/unit/validation.bats
bats tests/integration/lifecycle.bats --filter "non-blocking"
bats --recursive tests/ --filter "validate_port"

Test Architecture

Directory Layout

tests/
├── helpers/
│   └── test_helper.bash    # Shared setup/teardown
├── stubs/
│   ├── socat               # Mock socat (logs args, sleeps)
│   ├── ss                  # Mock ss (state-file-based output)
│   └── openssl             # Mock openssl (dummy cert/key)
├── fixtures/
│   ├── sample_session.session   # v2.2 session format
│   ├── legacy_session.pid       # v1.0 format (migration)
│   └── ports.conf               # Batch config
├── unit/
│   ├── validation.bats     # Input validation functions
│   └── session.bats        # Session management functions
└── integration/
    ├── lifecycle.bats       # Launch → status → stop
    ├── dual_stack.bats      # Protocol-scoped stop
    ├── capture.bats         # Traffic capture
    └── extended.bats        # Port detection, help, flags, watchdog

How Isolation Works

  1. Each @test runs in its own BATS subshell
  2. setup() creates a temp directory (TEST_TMPDIR)
  3. The script is symlinked into TEST_TMPDIR so SCRIPT_DIR resolves there
  4. All runtime directories (sessions/, logs/) are created in temp
  5. Stubs are prepended to PATH (works for exec'd commands in child processes)
  6. teardown() kills background jobs and removes the temp directory

What Unit Tests Cover

Pure function testing — no stubs, no background processes:

  • All validate_* functions (ports, hostnames, protocols, paths, session IDs)
  • generate_session_id, get_alt_protocol
  • session_register, session_read_field, session_find_by_*, session_cleanup_dead

What Integration Tests Cover

Multi-function flows with stubbed socat:

  • Launch → status → stop lifecycle
  • PID-file handoff verification
  • Process group isolation
  • Protocol-scoped stop
  • Dual-stack launch/stop independence
  • Traffic capture flag propagation
  • Port detection pattern matching
  • Per-mode help and flag validation
  • Watchdog stub behavior

Important: ss Stub Limitations

The ss stub cannot be reliably intercepted when called from within sourced script functions in BATS. Port detection tests use inline output pattern matching instead of calling the stub. See the extended.bats file header comments for the full explanation.

CI Pipeline

Every push triggers the test.yml workflow:

  1. ShellCheck lint on socat_manager.sh and bin/socat-manager
  2. BATS on Ubuntu 22.04 (bash 5.1), Ubuntu 24.04 (bash 5.2), Ubuntu 24.04 (bash 4.4 compiled)
  3. BATS on Docker containers: Debian 12, Kali Rolling, Rocky Linux 9, AlmaLinux 9, Arch Linux

Total: 8 test environments, 220 tests each = 1,760 test executions per push.

Makefile Targets

make help             # Show all targets
make check-deps       # Verify prerequisites (including flock)
make lint             # ShellCheck on all bash files (script, bin, stubs, helpers)
make test             # Full suite (lint + unit + integration)
make test-unit        # Unit only
make test-integration # Integration only
make test-smoke       # Quick smoke test (menu, help, version, status — no BATS)
make install          # System-wide install
make uninstall        # Remove installation
make verify           # Post-install verification (includes menu check)
make venv             # Create virtual environment
make dist             # Build release tarballs + checksums (includes wiki, .github)
make clean            # Remove build artifacts, test temps, lock files

Clone this wiki locally