-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
313 lines (254 loc) · 12.5 KB
/
Copy pathMakefile
File metadata and controls
313 lines (254 loc) · 12.5 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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
.POSIX:
export PATH := $(abspath bin/):${PATH}
# Dependency versions
LICENSEI_VERSION = 0.9.0
# run Go tests and generate a coverage report
#
# NOTE:
# The coverage counters are to be updated atomically,
# which is useful for tests that run in parallel.
.PHONY: test-with-coverage
test-with-coverage:
go test -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -html=coverage.out -o coverage.html
# run the unit tests across all packages in the tofu project
.PHONY: test
test:
go test -v ./...
EXT := $(shell go env GOEXE)
# build choudoufu binary in the current directory with the version set to the git tag
# or commit hash if there is no tag.
.PHONY: build
build:
go build -ldflags "-X main.version=$(shell git describe --tags --always --dirty)" -o choudoufu$(EXT) ./cmd/choudoufu
# Experimental engine building
.PHONY: build-experimental
build-experimental:
TOFU_X_EXPERIMENTAL_RUNTIME=1 go build -ldflags "-X main.version=$(shell git describe --tags --always --dirty) -X main.experimentsAllowed=yes" -o choudoufu$(EXT) ./cmd/choudoufu
# Experimental engine testing
.PHONY: test-experimental
test-experimental:
# TOFU_X_EXPERIMENTAL_RUNTIME=1 go test -ldflags "-X main.experimentsAllowed=yes" -v ./...
TOFU_X_EXPERIMENTAL_RUNTIME=1 go test -v -ldflags "-X main.experimentsAllowed=yes" -v ./internal/tofu
# generate runs `go generate` to build the dynamically generated
# source files, except the protobuf stubs which are built instead with
# "make protobuf".
.PHONY: generate
generate:
go generate ./...
# We separate the protobuf generation because most development tasks on
# OpenTofu do not involve changing protobuf files and protoc is not a
# go-gettable dependency and so getting it installed can be inconvenient.
#
# If you are working on changes to protobuf interfaces, run this Makefile
# target to be sure to regenerate all of the protobuf stubs using the expected
# versions of protoc and the protoc Go plugins.
.PHONY: protobuf
protobuf:
go tool protobuf-compile .
# Golangci-lint is installed first and then run twice to cover all platforms.
#
# $(CURDIR), not $(PWD): $(PWD) is the environment variable, and this
# repository's own test invocation has to unset it (/Users/alex/checkouts is a
# symlink and os.Getwd() honours PWD), which made `env -u PWD make
# golangci-lint` install into /tools and fail on a read-only filesystem. The
# two commands this repo needs should not have incompatible environments.
#
# Both passes run and the target fails if either did, rather than aborting on
# the first. The windows pass reported 11 findings for long enough that nobody
# had ever seen what the linux pass says, because make stopped there (#148).
.PHONY: golangci-lint
golangci-lint:
GOBIN=$(CURDIR)/tools go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6.0
@rc=0; \
for goos in windows linux; do \
echo "==> golangci-lint GOOS=$$goos"; \
GOOS=$$goos tools/golangci-lint${EXT} run --timeout 60m ./... || rc=1; \
done; \
exit $$rc
# Run license check
.PHONY: license-check
license-check:
go mod vendor
licensei cache --debug
licensei check --debug
licensei header --debug
rm -rf vendor/
git diff --exit-code
# This runs the copyright checks against the files in this repository.
# This is the same script that is used also in the .github/workflows/checks.yml. If this or that configuration is ever changed,
# be sure that the changes are reflected in both places.
copyright:
curl -fsSL https://raw.githubusercontent.com/opentofu/scripts/main/sh/copyright_check.sh | bash -s -- "" "*.go *.proto" "*/.git* */vendor/* */node_modules/* */.workdir* */website/* */tfplugin*.proto"
# Install dependencies
deps: bin/licensei
deps:
bin/licensei: bin/licensei-${LICENSEI_VERSION}
@ln -sf licensei-${LICENSEI_VERSION} bin/licensei
bin/licensei-${LICENSEI_VERSION}:
@mkdir -p bin
curl -sfL https://git.io/licensei | bash -s v${LICENSEI_VERSION}
@mv bin/licensei $@
# disallow any parallelism (-j) for Make. This is necessary since some
# commands during the build process create temporary files that collide
# under parallel conditions.
.NOTPARALLEL:
# Integration tests
#
.PHONY: list-integration-tests
list-integration-tests: ## Lists tests.
@ grep -h -E '^(test|integration)-.+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[1m%-30s\033[0m %s\n", $$1, $$2}'
# integration test with s3 as backend
.PHONY: test-s3
define infoTestS3
Test requires:
* AWS Credentials to be configured
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html
* IAM Permissions in us-west-2
- S3 CRUD operations on buckets which will follow the pattern tofu-test-*
- DynamoDB CRUD operations on a Table named dynamoTable
endef
test-s3: ## Runs tests with s3 bucket as the backend.
@ $(info $(infoTestS3))
@ TF_S3_TEST=1 go test ./internal/backend/remote-state/s3/...
# integration test with gcp as backend
.PHONY: test-gcp
define infoTestGCP
This test requires a working set of default credentials on the host.
You can configure those by running `gcloud auth application-default login`.
Additionally, you'll need to set the following environment variables:
- GOOGLE_REGION to a valid GCP region, e.g. us-west1
- GOOGLE_PROJECT to a valid GCP project ID
Note: The GCP tests leave behind a keyring, because those can't easily be deleted. It will be reused across test runs.
endef
test-gcp: ## Runs tests with gcp as the backend.
@ $(info $(infoTestGCP))
@ TF_ACC=1 go test ./internal/backend/remote-state/gcs/...
@ echo "Note: this test has left behind a keyring, because those can't easily be deleted. It will be reused across test runs."
# integration test with postgres as backend
.PHONY: test-pg test-pg-clean
PG_PORT := 5432
define infoTestPg
Test requires:
* Docker: https://docs.docker.com/engine/install/
* Port: $(PG_PORT)
endef
test-pg: ## Runs tests with local Postgres instance as the backend.
@ $(info $(infoTestPg))
@ echo "Starting database"
@ make test-pg-clean
@ docker run --rm -d --name tofu-pg \
-p $(PG_PORT):5432 \
-e POSTGRES_PASSWORD=tofu \
-e POSTGRES_USER=tofu \
postgres:16-alpine3.17 1> /dev/null
@ docker exec tofu-pg /bin/bash -c 'until psql -U tofu -c "\q" 2> /dev/null; do echo "Database is getting ready, waiting"; sleep 1; done'
@ DATABASE_URL="postgres://tofu:tofu@localhost:$(PG_PORT)/tofu?sslmode=disable" \
TF_PG_TEST=1 go test ./internal/backend/remote-state/pg/...
test-pg-clean: ## Cleans environment after `test-pg`.
@ docker rm -f tofu-pg 2> /dev/null
# integration test with Azure as backend
.PHONY: test-azure
test-azure: ## Directs the developer to follow a runbook describing how to run Azure integration tests.
@ echo "To run Azure integration tests, please follow the runbook in internal/backend/remote-state/azure/README.md".
@ exit 1 # don't want the user to miss this
# integration test with Consul as backend
.PHONY: test-consul test-consul-clean
define infoTestConsul
Test requires:
* Docker: https://docs.docker.com/engine/install/
endef
GO_VER := `go tool github.com/intentius/choudoufu/tools/selected-go-version`
test-consul: ## Runs tests using in docker container using Consul as the backend.
@ $(info $(infoTestConsul))
@ echo "Build docker image with Consul and Go v$(GO_VER)"
@ cd ./internal/backend/remote-state/consul &&\
docker build --build-arg="GO_VERSION=${GO_VER}" -t tofu-consul --progress=plain . &> /dev/null
@ echo "Run tests"
@ docker run --rm --name tofu-consul -v $(PWD):/app -e TF_CONSUL_TEST=1 -t tofu-consul \
test ./internal/backend/remote-state/consul/...
test-consul-clean: ## Cleans environment after `test-consul`.
@ docker rmi -f tofu-consul:latest
# integration test with kubernetes as backend
.PHONY: test-kubernetes test-kubernetes-clean
define infoTestK8s
Test requires:
* Git client
* Docker: https://docs.docker.com/engine/install/
Note! Please make sure that the docker configurations satisfy requirements: https://kind.sigs.k8s.io/docs/user/quick-start#settings-for-docker-desktop
endef
KIND_VERSION := v0.20.0
test-kubernetes: test-kubernetes-clean ## Runs tests with a local kubernetes cluster as the backend.
@ $(info $(infoTestK8s))
@ echo "Installing KinD $(KIND_VERSION): https://kind.sigs.k8s.io/docs/user/quick-start/#installing-with-make"
@ git clone -c advice.detachedHead=false -q https://github.com/kubernetes-sigs/kind -b $(KIND_VERSION) /tmp/kind-repo 1> /dev/null && \
cd /tmp/kind-repo &&\
make build 1> /dev/null &&\
mv ./bin/kind /tmp/tofuk8s &&\
cd .. && rm -rf kind-repo
@ echo "Provisioning a cluster"
@ /tmp/tofuk8s -q create cluster --name tofu-kubernetes
@ /tmp/tofuk8s -q export kubeconfig --name tofu-kubernetes --kubeconfig /tmp/tofu-k8s-config
@ echo "Running tests"
@ KUBE_CONFIG_PATHS=/tmp/tofu-k8s-config TF_K8S_TEST=1 go test ./internal/backend/remote-state/kubernetes/...
@ echo "Deleting provisioned cluster"
@ make test-kubernetes-clean
test-kubernetes-clean: ## Cleans environment after `test-kubernetes`.
@ test -s /tmp/tofu-k8s-config && rm /tmp/tofu-k8s-config || echo "" > /dev/null
@ test -s /tmp/tofuk8s && (/tmp/tofuk8s -q delete cluster --name tofu-kubernetes && rm /tmp/tofuk8s) || echo "" > /dev/null
# integration test for the stateless mode, against the floci AWS emulator
.PHONY: test-floci test-floci-clean
# The pinned emulator image; live/floci-image is the single source (#98).
# This had drifted to upstream floci/floci:latest, so test-floci-clean was
# cleaning containers of an image nothing here runs.
#
# ?= rather than := so an exported FLOCI_IMAGE wins, which is what
# internal/live/flocitest and live/e2e/run.sh both already do. With :=, a run
# under an overridden image started containers this target could not see, and
# test-floci-clean went back to cleaning nothing - the same silent no-op the
# drifted literal caused, reached a different way (issue #145).
FLOCI_IMAGE ?= $(shell cat live/floci-image)
define infoTestFloci
Test requires:
* Docker: https://docs.docker.com/engine/install/
* The AWS CLI, which reads the emulated cloud back independently of tofu
* terraform on PATH, which stands up the estates these tests recover
* Ports in the 4603-4632 range: every test runs its own emulator
Each test applies a real estate to the emulator, so the tier takes tens of
minutes. Set TF_ACC=1 instead of TF_FLOCI_TEST=1 to run it as part of a
wider acceptance run.
endef
test-floci: ## Runs the stateless-mode tests against the floci AWS emulator.
@ $(info $(infoTestFloci))
@ TF_FLOCI_TEST=1 go test -count=1 -timeout 60m ./internal/live/... ./internal/command/... ./tools/estate-gen/... ./tools/survey-gen/... ./tools/terralith-gen/...
# issue #64's scale benchmark: an N-resource estate (tools/estate-gen -count),
# planned against floci with every API call counted. ESTATE_BENCH_N overrides
# the estate size (default 200, the committed live/plan-budget.json's own N);
# a run at that default N also ratchets against the budget. See
# internal/live/discovery/scale_bench_test.go's doc comment for the measured
# scaling curve and internal/live/cloudcontrol/doc.go's "Retries" section for
# the backoff policy this same issue asked for.
.PHONY: bench-estate
bench-estate: ## Runs issue #64's estate-scale benchmark against floci. ESTATE_BENCH_N sets the estate size (default 200).
@ TF_FLOCI_TEST=1 go test -count=1 -timeout 30m -v ./internal/live/discovery/ -run TestScaleAgainstFloci
test-floci-clean: ## Removes floci containers left behind by `test-floci`.
@ docker ps -aq --filter ancestor=$(FLOCI_IMAGE) | while read -r id; do docker rm -f $$id > /dev/null; done
.PHONY:
integration-tests: test-s3 test-pg test-consul test-kubernetes test-floci integration-tests-clean ## Runs all integration tests test.
.PHONY:
integration-tests-clean: test-pg-clean test-consul-clean test-kubernetes-clean test-floci-clean ## Cleans environment after all integration tests.
.PHONY: help
help: ## Prints this help message.
@echo ""
@echo "Opentofu Makefile"
@echo ""
@echo "Usage: make [target]"
@echo ""
@echo "The available targets for execution are listed below."
@echo ""
@echo "Targets:"
@awk 'BEGIN {FS = ":.*$$"; OFS = ""} \
/^# .*$$/ { doc=$$0; sub(/^# /, "", doc); next } \
/^[a-zA-Z0-9_-]+:.*## .*$$/ { target=$$1; sub(/:$$/, "", target); desc=$$0; sub(/^[^#]*## /, "", desc); if (!seen[target]++) { printf "\033[1m%-30s\033[0m %s\n", target, desc } } \
/^[a-zA-Z0-9_-]+:.*$$/ { target=$$1; sub(/:$$/, "", target); if (!seen[target]++) { if (doc != "") { printf "\033[1m%-30s\033[0m %s\n", target, doc; doc="" } else { printf "\033[1m%-30s\033[0m\n", target } } }' $(MAKEFILE_LIST)