Skip to content

Latest commit

 

History

History
302 lines (209 loc) · 8.53 KB

File metadata and controls

302 lines (209 loc) · 8.53 KB

Sandbox Testing Guide

How to safely test dotbak without risking your real dotfiles or system.


Why Sandbox?

dotbak touches real files on your system:

  • add --symlink replaces your original file with a symlink
  • install.sh writes to /usr/local/bin and shell completion directories
  • dotbak update overwrites the installed binary
  • DOTBAK_DIR env var, if set in your shell, can leak into tests and hit real directories

The bats test suite handles this by overriding HOME to a temp directory. But when you're manually testing commands, building, or running install/update — you need your own sandbox.


Quick Sandbox (No Docker Needed)

The fastest way to get an isolated environment. Open a new terminal and run:

# Create a disposable sandbox
SANDBOX=$(mktemp -d /tmp/dotbak-sandbox.XXXXXX)
export HOME="$SANDBOX/home"
mkdir -p "$HOME"
unset DOTBAK_DIR

echo "Sandbox active: HOME=$HOME"
echo "Your real home is untouched."

Now you can safely run any dotbak command:

# Everything happens inside the sandbox
cd /path/to/dotbak

./dotbak-dev init
echo "test config" > "$HOME/.zshrc"
./dotbak-dev add --symlink "$HOME/.zshrc"
./dotbak-dev status
./dotbak-dev remove "$HOME/.zshrc"

# Build and install to a temp location
./build.sh
mkdir -p "$SANDBOX/bin"
cp dotbak "$SANDBOX/bin/"
"$SANDBOX/bin/dotbak" --version

When you're done:

rm -rf "$SANDBOX"
# Or just close the terminal — it's in /tmp

What you can test here: All dotbak commands (init, add, remove, status, snapshot, symlink-sync, deploy, archive), build.sh, and manual install to a custom path.

What you can't test here: dotbak update (needs a real GitHub release), system-level install paths (/usr/local/bin), shell completions loading.


Container (Full Isolation)

Three dedicated containers in sandbox/ for different scenarios. Examples use podman — replace with docker if that's what you have.

All commands run from the project root (not from sandbox/):

cd /path/to/dotbak

Why localhost/? Podman doesn't have a default registry. Without the prefix, it prompts you to pick one. localhost/ tells it to use the locally built image.

Unit + integration tests

Runs the full bats test suite:

podman build -f sandbox/Dockerfile.test -t dotbak-test .
podman run --rm localhost/dotbak-test

Run specific tests:

podman run --rm localhost/dotbak-test ./test.sh unit
podman run --rm localhost/dotbak-test ./test.sh test/integration/test_add.bats

Install lifecycle test

podman build -f sandbox/Dockerfile.install -t dotbak-install .

Automated checks (pass/fail):

podman run --rm localhost/dotbak-install                                      # full cycle
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh install    # install only
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh update     # reinstall only
podman run --rm localhost/dotbak-install ./sandbox/test-install.sh uninstall  # uninstall only

See real output (as a user would see it):

podman run --rm localhost/dotbak-install ./sandbox/demo.sh              # full cycle
podman run --rm localhost/dotbak-install ./sandbox/demo.sh install      # install output
podman run --rm localhost/dotbak-install ./sandbox/demo.sh update       # reinstall output
podman run --rm localhost/dotbak-install ./sandbox/demo.sh uninstall    # uninstall output

Both scripts refuse to run outside a container for safety.

Explore manually:

podman run --rm -it localhost/dotbak-install bash

Interactive dev (live mount)

Full dev environment with your source bind-mounted. Edit on your host, test inside the container:

podman build -f sandbox/Dockerfile.dev -t dotbak-dev-env .
podman run --rm -it -v "$(pwd):/dotbak:Z" localhost/dotbak-dev-env

Note: The :Z suffix is for SELinux (Fedora/RHEL). Drop it on Ubuntu/macOS.

Inside you can run ./dotbak-dev, ./build.sh, ./test.sh, shellcheck, etc. Changes to source files on your host are reflected immediately.

When to rebuild

  • test / install: Rebuild after changing source (they COPY the project in)
  • dev: Rarely — source is mounted live. Only rebuild if system deps change

Limitations

  • No macOS testing — containers run Linux only. For macOS, use a VM (see below).
  • No dotbak update — needs a real GitHub release with published artifacts.

For the full sandbox reference, see sandbox/README.md.


VM (Full OS Isolation)

When you need real multi-platform testing — especially macOS, or testing shell integration (login shells, completions, PATH setup).

Tools

Platform Recommended
Linux host QEMU/libvirt (virt-manager), VirtualBox
macOS host UTM (Apple Silicon), VirtualBox (Intel)
Any host Vagrant (automates VM provisioning)

Setup

# Inside the VM
git clone --recurse-submodules https://github.com/darshithedpara/dotbak
cd dotbak

# Install dependencies
# Ubuntu/Debian:
sudo apt install bash gcc shc zip unzip curl git
# Fedora:
sudo dnf install bash gcc shc zip unzip curl git
# macOS:
brew install bash shc zip

# Full test cycle
./test.sh
./build.sh
./install.sh
dotbak init
dotbak --version

When to use a VM

  • Testing macOS native builds (shc produces Mach-O binaries)
  • Testing shell completion loading in real login shells
  • Testing install/uninstall with real system paths
  • Reproducing CI failures on a specific OS version

CI as Sandbox

GitHub Actions CI already provides isolated testing on every push and PR:

  • Ephemeral runners — each run starts clean, no cleanup needed
  • Multi-platform — Ubuntu + macOS matrix
  • Full pipeline — ShellCheck, build, test suite, version verification

Trigger CI

Push to a branch or open a PR against main. CI runs automatically.

Local CI with act

Run GitHub Actions workflows locally using act:

# Install act
# Fedora: sudo dnf install act
# macOS: brew install act
# Others: https://github.com/nektos/act#installation

# Run the CI workflow locally
act push

# Run a specific job
act push -j test
act push -j shellcheck

act uses a container runtime under the hood. It works with both Docker and podman (export DOCKER_HOST=... for podman socket).


Git-Tracking Your Dotbak Directory

After dotbak init, you can version-control your entire ~/.dotbak directory with git. This gives you full history of your dotfile changes, and you can push to a private repo for cross-machine sync.

# Initialize git inside your dotbak directory
cd ~/.dotbak
git init
git add -A
git commit -m "initial dotbak backup"

# Optional: push to a private repo
git remote add origin git@github.com:youruser/dotfiles-backup.git
git push -u origin main

Workflow with git

# After making changes to your dotfiles:
dotbak snapshot                 # create a dotbak snapshot
cd ~/.dotbak
git add -A
git commit -m "update zshrc and nvim config"
git push

On a new machine

# Clone your dotfiles backup
git clone git@github.com:youruser/dotfiles-backup.git ~/.dotbak

# Deploy everything
dotbak deploy --all

This pairs well with the sandbox approach — test the full init -> add -> snapshot -> git push -> clone -> deploy cycle inside a sandbox or Docker container before doing it for real.


Safety Checklist

Before running dotbak commands outside the test suite, verify:

  • echo $HOME — is it a temp/sandbox directory?
  • echo $DOTBAK_DIR — is it unset or pointing to a sandbox path?
  • Using dotbak-dev? — not the system-installed dotbak
  • Install testing? — using a temp prefix, not /usr/local/bin
  • Symlink testing? — files you're adding are dummy files in the sandbox, not real configs

The DOTBAK_DIR trap

If you have export DOTBAK_DIR=... in your shell profile, it overrides $HOME/.dotbak in all contexts — including tests. The bats test suite does not unset this variable. Before running tests:

unset DOTBAK_DIR
./test.sh

Summary

Method Isolation Setup time Can test install? macOS?
Quick sandbox HOME override 10 seconds Partial (custom path) Yes
Container (podman/docker) Full container 1 minute Yes No
VM Full OS 10-30 minutes Yes Yes
CI (GitHub Actions) Ephemeral runner Push and wait Yes Yes
act (local CI) Container-based 2 minutes Yes No