-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathMakefile
More file actions
161 lines (140 loc) · 6.1 KB
/
Copy pathMakefile
File metadata and controls
161 lines (140 loc) · 6.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# Thundersnap Makefile
#
# Development targets:
# make test - run all tests
# make e2e - run e2e tests (requires sudo and btrfs)
# make binaries - build all binaries for local development
# make ts - build just the ts binary
#
# Distribution targets:
# make build - build distribution packages (deb, rpm, tgz)
# make build-deb - build only .deb packages
# make list - list all available build targets
#
# Note: cmd/ts requires CGO_ENABLED=0 because it runs inside containers/VMs
# where dynamically linked binaries may not work. The Makefile handles this.
DIST_CMD = go run ./cmd/dist
# Default output directory for packages
OUT ?= dist
# Output directory for local binaries
BIN ?= ./bin
.PHONY: all test e2e not_e2e binaries ts vshd thundersnapd bupdate fidx slab \
list build build-deb build-rpm build-tgz clean
all: build
# Run all unit tests (requires CGO_ENABLED=0 for cmd/ts tests).
#
# Two timeouts, layered:
# - go test -timeout 30s: PER-PACKAGE soft timeout. go test compiles each
# package into its own test binary and runs them in turn; -timeout caps
# each binary's run, so a 5s test that takes 29s counts as a pass but one
# that hits 30s panics (a should-be-fast test running long is caught).
# The build (go test -c, cache misses, module downloads) is NOT counted
# against this -- only the test run.
# - external `timeout -s KILL 60s`: GLOBAL hard safety net. go test's
# -timeout fires a panic on the test goroutine, which a goroutine blocked
# in a syscall (e.g. a test hung on a socket read) won't receive until the
# syscall returns -- so a truly hung test may not die from -timeout alone.
# The external SIGKILL guarantees the whole run ends. 60s is generous:
# unit tests are sub-second (for contrast the e2e suite boots real KVM VMs
# in ~0.1s and whole tests finish in seconds), so hitting either timeout
# almost always means a real hang/bug, not a slow test.
#
# If the tests pass, also verify all Go files are gofmt-formatted; fail if not.
test:
CGO_ENABLED=0 timeout -s KILL 60s go test -timeout 30s ./...
@echo "checking gofmt..."
@unformatted=$$(gofmt -l $$(find . -name '*.go' -not -path './.tmp-e2e/*' -not -path './vendor/*' 2>/dev/null)); \
if [ -n "$$unformatted" ]; then \
echo "ERROR: the following files are not gofmt-formatted:"; \
echo "$$unformatted"; \
echo "run 'gofmt -w .' to fix"; \
exit 1; \
fi
@echo "gofmt OK"
# Run e2e tests (requires root and btrfs).
# These are true end-to-end tests that start a real thundersnapd and SSH into it.
# Compiles the test binary and dependencies as the current user (untimed), then
# runs with sudo. TMPDIR must be on btrfs (not /tmp which is typically tmpfs).
#
# Timeouts are extremely generous relative to reality: the tests boot real KVM
# VMs in ~0.1s and each test finishes in a few seconds, so the 2m go-test
# -test.timeout and the 120s Makefile-level hard cap both leave enormous
# headroom — hitting either almost always means a real hang/bug, not a slow
# test. E2E_ARGS can be used to pass extra args (e.g., E2E_ARGS="-run TestFoo").
#
# test-cleanup.sh reclaims leftover btrfs subvols and sets .tmp-e2e to 0700
# root before the run (clean slate) and after a SUCCESSFUL run (reclaim
# orphans). On failure the cleanup is skipped so orphans remain for debugging.
E2E_TMPDIR ?= $(CURDIR)/.tmp-e2e
E2E_TEST_TIMEOUT ?= 2m
E2E_ARGS ?=
NOT_E2E_TEST_TIMEOUT ?= 2m
e2e: ts vshd thundersnapd
@mkdir -p $(E2E_TMPDIR)
@./test-cleanup.sh $(E2E_TMPDIR)
CGO_ENABLED=0 go test -tags e2e -c -o $(BIN)/e2e.test ./e2e
sudo -E timeout 120s env \
TMPDIR="$(E2E_TMPDIR)" \
TS_BINARY="$(CURDIR)/$(BIN)/ts" \
VSHD_BINARY="$(CURDIR)/$(BIN)/vshd" \
THUNDERSNAPD_BINARY="$(CURDIR)/$(BIN)/thundersnapd" \
$(BIN)/e2e.test -test.v -test.failfast -test.timeout=$(E2E_TEST_TIMEOUT) $(E2E_ARGS)
@./test-cleanup.sh $(E2E_TMPDIR)
# Run legacy "e2e" tests (not actually e2e - see not-e2e-enough.md).
# These tests exercise individual components but don't go through the SSH front
# door. Same timeout philosophy as `e2e`: the 2m go-test -test.timeout and 240s
# Makefile-level hard cap are both extremely generous (the tests, including the
# ones that boot KVM VMs, finish in seconds); a timeout means a real hang/bug.
# test-cleanup.sh runs before (clean slate) and after a successful run; on
# failure it is skipped so orphans remain for debugging.
not_e2e: ts vshd thundersnapd
@mkdir -p $(E2E_TMPDIR)
@./test-cleanup.sh $(E2E_TMPDIR)
CGO_ENABLED=0 go test -tags e2e -c -o $(BIN)/not_e2e.test ./not_e2e
sudo -E timeout 240s env \
TMPDIR="$(E2E_TMPDIR)" \
TS_BINARY="$(CURDIR)/$(BIN)/ts" \
VSHD_BINARY="$(CURDIR)/$(BIN)/vshd" \
THUNDERSNAPD_BINARY="$(CURDIR)/$(BIN)/thundersnapd" \
$(BIN)/not_e2e.test -test.v -test.failfast -test.timeout=$(NOT_E2E_TEST_TIMEOUT) $(E2E_ARGS)
@./test-cleanup.sh $(E2E_TMPDIR)
# Build all binaries for local development
binaries: ts vshd thundersnapd
# Binaries that need CGO_ENABLED=0 (run inside containers/VMs)
ts:
@mkdir -p $(BIN)
CGO_ENABLED=0 go build -o $(BIN)/$@ ./cmd/$@
vshd:
@mkdir -p $(BIN)
CGO_ENABLED=0 go build -o $(BIN)/$@ ./cmd/$@
# Binaries that can use default CGO setting
# thundersnapd: CGO_ENABLED=0 so the nested test (nested_test.go) can run it
# inside a minimal container rootfs that lacks shared libraries.
thundersnapd:
@mkdir -p $(BIN)
CGO_ENABLED=0 go build -o $(BIN)/$@ ./cmd/$@
# List all available build targets
list:
$(DIST_CMD) list
# Build all packages (deb, rpm, tgz for all architectures)
build:
$(DIST_CMD) build --out "$(OUT)" all
# Build only .deb packages
build-deb:
$(DIST_CMD) build --out "$(OUT)" "deb"
# Build only the thundersnap-dev .deb package (for blue/green deployment)
build-deb-dev:
$(DIST_CMD) build --out "$(OUT)" "deb-dev"
# Build only .rpm packages
build-rpm:
$(DIST_CMD) build --out "$(OUT)" "rpm"
# Build only .tgz tarballs
build-tgz:
$(DIST_CMD) build --out "$(OUT)" "tgz"
# Build for a specific architecture (e.g., make build-amd64, make build-arm64)
build-amd64:
$(DIST_CMD) build --out "$(OUT)" "linux/amd64"
build-arm64:
$(DIST_CMD) build --out "$(OUT)" "linux/arm64"
clean:
rm -rf "$(OUT)" "$(BIN)"