testing-e2e-containers
E2E Container Testing
Test the installer binary inside Docker containers running the supported Linux distributions.
Workflow
- Build the installer for the container platform
- Start a fresh container
- Run the installer inside it
- Verify results
- Stop the container
- Repeat for each distro (ubuntu, debian, fedora)
Step 1: Build the Binary
Use goreleaser to build snapshot binaries for all platforms defined in .goreleaser.yaml. Run from the installer/ directory:
cd installer && goreleaser build --skip before --snapshot --clean
This produces binaries under installer/dist/, one per OS-arch combo. The docker-compose volumes mount installer/ into containers at /workspace/installer, so the binary path inside the container follows this pattern:
/workspace/installer/dist/dotfiles_installer_<os>_<arch>/dotfiles-installer
For example, on a macOS ARM host (Apple Silicon) running Linux ARM64 containers:
/workspace/installer/dist/dotfiles_installer_linux_arm64_v8.0/dotfiles-installer
For Linux AMD64 containers:
/workspace/installer/dist/dotfiles_installer_linux_amd64_v1/dotfiles-installer
Step 2: Run Tests in Containers
Start a fresh container for each test scenario to avoid state leakage from previous runs. Reuse the image, but always start from scratch.
cd installer/docker
# Start container
task ubuntu:start
# Run the installer (adjust flags for the scenario being tested)
docker-compose -f ubuntu/docker-compose.yml exec --user testuser installer-test-ubuntu \
sudo /workspace/installer/dist/dotfiles_installer_linux_arm64_v8.0/dotfiles-installer install \
--shell zsh --shell-source auto --non-interactive --install-prerequisites
# Verify results (scenario-dependent)
# ...
# Tear down before next test
task ubuntu:stop
For standalone containers (without docker-compose), bind-mount the dist directory explicitly:
docker run -d --name test-ubuntu --platform linux/arm64 \
-v "$(pwd)/../dist:/workspace/installer/dist:ro" \
ubuntu-installer-test-ubuntu:latest tail -f /dev/null
docker exec test-ubuntu /workspace/installer/dist/dotfiles_installer_linux_arm64_v8.0/dotfiles-installer install \
--shell zsh --shell-source system --non-interactive
docker stop test-ubuntu && docker rm test-ubuntu
Step 3: Verify Results
Verification depends on what the test scenario is exercising. After running the installer, determine appropriate checks based on the flags and features being tested, then run them inside the container using docker-compose exec or docker exec.
Testing All Distros
Run through all three distros. Always stop before starting the next test:
cd installer/docker
for distro in ubuntu debian fedora; do
task ${distro}:start
# ... run installer and verify ...
task ${distro}:stop
done
Interactive GPG Testing
For testing the GPG key setup flow interactively (which requires automating GPG's prompts), see the testing-interactive-gpg skill.
Gotchas
- See distro-specific notes for platform quirks (zsh paths, brew behavior, package manager differences)
- Homebrew's first run downloads portable Ruby (~30MB) and can take several minutes
- Fedora's first
dnftriggers a repo metadata sync (~30MB) - be patient or use generous timeouts - If brew errors with "process has already locked", a previous install was interrupted - start a fresh container
- When running long tests, prefer running in background and polling for completion over setting very long timeouts
More from mrpointer/dotfiles
configuring-zsh
Configure and troubleshoot Zsh shell. Use when editing .zshenv, .zprofile, .zshrc, .zlogin, or .zlogout, setting up powerlevel10k prompt, configuring oh-my-zsh or sheldon plugin manager, fixing PATH or environment variables, debugging slow shell startup, setting up completions/compinit/fpath, or working with zsh-autocomplete, zsh-autosuggestions, or zsh-syntax-highlighting plugins.
20configuring-github-actions
Create and troubleshoot GitHub Actions workflows. Use when editing .github/workflows files, setting up CI/CD pipelines, configuring matrix builds for multi-platform testing, debugging failing workflows, adding caching or artifacts, running E2E tests in containers, or asking "why is my workflow failing" or "how do I test on multiple OSes".
11managing-chezmoi
Manage dotfiles with chezmoi. Use when adding files to chezmoi, running chezmoi add/apply/diff/status, debugging why changes aren't appearing, working with chezmoi templates or .chezmoiignore, understanding source vs target files, resolving merge conflicts, or asking "how do I manage this file with chezmoi". For chezmoi command uncertainties, use Context7 to fetch latest docs.
2writing-go-tests
Write Go tests following project conventions. Use when creating test files, writing unit or integration tests, choosing mocks, or setting up test fixtures. Covers test naming, assertions, mock usage, table-driven patterns, and common pitfalls.
1writing-go-code
Apply Go coding standards when writing or modifying Go code. Use when implementing functions, using dependency injection, handling errors idiomatically, or working with interfaces. For test conventions, use the `writing-go-tests` skill instead.
1testing-go-code
Run Go unit tests, coverage reports, and benchmarks. Use when you need to run tests, check coverage, run benchmarks, or regenerate mocks after interface changes.
1