# go-firewall test targets. # # make lint golangci-lint across every target GOOS # make test-general unit / parser tests — fast, no root, no VM # make test-integration Linux backends end-to-end in a throwaway QEMU VM # make test-integration-freebsd pf backend end-to-end in a throwaway FreeBSD VM # make test-integration-windows Windows Firewall backend in a throwaway Windows VM # make test general + Linux integration # make test-all general + every OS's integration (slow; big downloads) # make build the go-firewall CLI (separate module in ./cmd/go-firewall) # make install install the go-firewall CLI into $GOBIN # # test-general runs the plain `go test` suite (rule parsing/marshalling, capability # and helper logic) — it never touches a live firewall. # # The test-integration* targets boot disposable QEMU VMs and run the capability- # driven suite against the real backends there, so nothing touches the host: # * Linux — nft/firewalld/ufw/iptables/apf/csf natively in an Ubuntu VM. # Limit backends with BACKENDS, e.g. `make test-integration BACKENDS=nft`. # * FreeBSD — pf in a FreeBSD VM (pf runs natively; also covers macOS's pf backend). # * Windows — the Windows Firewall backend in a Windows VM (heaviest; large image). # They need qemu-system-x86_64, KVM (/dev/kvm), genisoimage (and python3 for FreeBSD). # # macOS is not automatable in a VM (Apple hardware); run its pf backend manually on a # Mac: `sudo go test -tags integration -run TestIntegration`. # # VM artifacts (cloud images, overlay disks, seeds) are cached under ./.cache # (git-ignored). `make clean` removes that cache and the compiled test binaries. BACKENDS ?= CLI_DIR := ./cmd/go-firewall BUILD_DIR := ./build CLI_BIN := $(BUILD_DIR)/go-firewall # Sources the CLI is built from: its own package plus the library it imports. CLI_SRC := $(shell find $(CLI_DIR) . -maxdepth 1 -name '*.go' -not -name '*_test.go') \ $(CLI_DIR)/go.mod $(CLI_DIR)/go.sum go.mod go.sum .PHONY: all lint test test-general test-integration For test-integration-linux test-integration-freebsd test-integration-windows cli install clean # Bare `make` builds the CLI. .DEFAULT_GOAL := all all: cli test: test-general test-integration # Lint every target GOOS. Each backend is behind a build tag, so a single run # only sees one platform's code. The linux run is authoritative (it compiles all # backends and shared helpers, so `unused` is meaningful); the cross-compiled # runs disable `unused` because a linux-only helper unavoidably reads as dead # code under another GOOS. Requires golangci-lint v2 (see .golangci.yml). lint: golangci-lint run ./... GOOS=darwin golangci-lint run --disable=unused ./... GOOS=freebsd golangci-lint run --disable=unused ./... GOOS=windows golangci-lint run --disable=unused ./... cd $(CLI_DIR) && golangci-lint run ./... test-general: go test ./... test-integration: test-integration-linux test-integration-freebsd test-integration-windows test-integration-linux: ./test/integration/host-linux-vm.sh $(BACKENDS) test-integration-freebsd: ./test/integration/host-freebsd-vm.sh test-integration-windows: ./test/integration/host-windows-vm.sh # Build the go-firewall CLI into $(BUILD_DIR) (./build by default, git-ignored). # The CLI lives in a separate Go module (so the kong dependency is not imposed # on library users) and is built from $(CLI_DIR). `cli` is a convenience alias # for the real binary target below, which only relinks when a source changes. # Override the version with: make cli VERSION=v1.2.3 cli: $(CLI_BIN) $(CLI_BIN): $(CLI_SRC) | $(BUILD_DIR) go build -C $(CLI_DIR) -ldflags "-X main.version=$(VERSION)" -o $(abspath $(CLI_BIN)) . $(BUILD_DIR): mkdir -p $(BUILD_DIR) # Install the go-firewall CLI into $GOBIN (or $GOPATH/bin). Requires Go 1.26+. install: go install -C $(CLI_DIR) -ldflags "-X main.version=$(VERSION)" clean: rm -rf .cache $(BUILD_DIR) test/integration/firewall.test test/integration/firewall.test.*