-
-
Notifications
You must be signed in to change notification settings - Fork 315
Expand file tree
/
Copy pathtestacc
More file actions
executable file
·438 lines (381 loc) · 14.2 KB
/
Copy pathtestacc
File metadata and controls
executable file
·438 lines (381 loc) · 14.2 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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
#
set -e
set -u
BASE_PKG="github.com/bpg/terraform-provider-proxmox"
DEFAULT_TIMEOUT="30m"
KNOWN_TIERS="light medium heavy"
KNOWN_RESOURCES="access acme apt backup ceph container datastores file firewall ha hardwaremapping metrics misc network options pool replication sdn storage vm"
show_help() {
cat <<'EOF'
Usage: ./testacc [OPTIONS] [TEST_NAME] [-- GO_TEST_FLAGS...]
Run acceptance tests for the Proxmox Terraform provider.
Arguments:
TEST_NAME Name of the test to run (e.g., TestAccResourceVM2CPU)
Supports patterns like TestAccResourceVM.* for multiple tests
If omitted, runs all acceptance tests
Options:
--all Run all acceptance tests (same as omitting TEST_NAME)
--tier TIERS Run tests by tier: light, medium, heavy, or all
Comma-separated for multiple: --tier light,medium
--resource NAME Run tests for a resource type (e.g., vm, sdn, firewall)
--packages N Max concurrent packages (default: varies by tier)
--parallel N Max concurrent tests per package (default: 4)
--no-proxy Disable HTTP/HTTPS proxy for this test run
--show-command Show the exact go test command being executed
-h, --help Show this help message
Examples:
./testacc # Run all tiers sequentially
./testacc --tier light # Light tests only (~30s)
./testacc --tier medium # Medium tests only (~3 min)
./testacc --tier heavy # Heavy tests only (~15 min)
./testacc --tier light,medium # Light + medium (~3.5 min)
./testacc --tier all # All tiers with smart parallelism
./testacc --resource vm # All VM-related tests
./testacc --resource sdn # All SDN tests
./testacc TestAccResourceVM2CPU # Single test by name
./testacc "TestAccDatasource.*" # Pattern match
./testacc --no-proxy TestAccDatasourceFile # Without proxy
./testacc TestAccDatasourceFile -- -count 2 # Extra go test flags
Notes:
- Single test names use exact matching (^TestName$) for efficiency
- Patterns with .* or * match multiple tests
- The script automatically finds the package containing the test
- Always quote pattern arguments to prevent shell expansion
- --tier and --resource cannot be combined with a TEST_NAME
Environment:
Acceptance tests require a testacc.env file in the project root with:
TF_ACC=1
PROXMOX_VE_API_TOKEN="root@pam!<token>=<value>"
PROXMOX_VE_ENDPOINT="https://<host>:8006/"
PROXMOX_VE_SSH_AGENT="true"
PROXMOX_VE_SSH_USERNAME="root"
EOF
}
find_test_package() {
test_name="${1:-}"
is_pattern="${2:-0}"
if [ -z "$test_name" ]; then
printf '%s\n' "${BASE_PKG}/fwprovider/..."
return
fi
# If it's a pattern, search all packages for efficiency
if [ "$is_pattern" = "1" ]; then
printf 'Searching all packages for pattern match\n' >&2
printf '%s\n' "${BASE_PKG}/fwprovider/..."
return
fi
# For exact test names, find the specific package
# Search only in test files for the function definition
test_file=$(find ./fwprovider -name "*_test.go" -type f -print0 2>/dev/null | \
xargs -0 grep -l "^func ${test_name}(" 2>/dev/null | head -n 1)
if [ -z "$test_file" ]; then
printf 'Warning: Test '\''%s'\'' not found in codebase\n' "$test_name" >&2
printf ' Searching all packages (this may be slower)\n' >&2
printf '%s\n' "${BASE_PKG}/fwprovider/..."
return
fi
package_dir=$(dirname "$test_file")
package_path=$(printf '%s\n' "$package_dir" | sed 's|^\./||')
printf 'Found test in: %s\n' "$test_file" >&2
printf '%s\n' "${BASE_PKG}/${package_path}"
}
validate_env_file() {
# Basic validation of testacc.env format
# Check if file is readable and not empty
if [ ! -r "testacc.env" ]; then
printf 'Error: testacc.env is not readable\n' >&2
return 1
fi
if [ ! -s "testacc.env" ]; then
printf 'Error: testacc.env is empty\n' >&2
return 1
fi
return 0
}
# Discover packages by testacc annotation.
# Usage: discover_packages "tier" "light"
# Returns: space-separated list of Go package paths (empty string if none found)
#
# For tier queries, only returns packages where ALL test files match the
# requested tier. A package with both light and heavy tests is excluded
# from --tier light (it belongs in --tier heavy).
discover_packages() {
annotation_key="$1"
annotation_value="$2"
# Find packages containing files with the requested annotation (anchored match)
matching_dirs=$(grep -rl "//testacc:${annotation_key}=${annotation_value}$" ./fwprovider/ 2>/dev/null \
| xargs -I{} dirname {} \
| sort -u)
[ -z "$matching_dirs" ] && return
if [ "$annotation_key" = "tier" ] && [ "$annotation_value" != "all" ]; then
# For tier filtering: exclude packages that also contain heavier tiers
exclude_tiers=""
case "$annotation_value" in
light) exclude_tiers="medium\|heavy" ;;
medium) exclude_tiers="heavy" ;;
heavy) exclude_tiers="" ;;
esac
if [ -n "$exclude_tiers" ]; then
heavier_dirs=$(grep -rl "//testacc:tier=\(${exclude_tiers}\)$" ./fwprovider/ 2>/dev/null \
| xargs -I{} dirname {} \
| sort -u)
# Filter out packages that also have heavier tiers (POSIX-compatible)
filtered=""
for dir in $matching_dirs; do
excluded=0
for hdir in $heavier_dirs; do
if [ "$dir" = "$hdir" ]; then
excluded=1
break
fi
done
if [ "$excluded" = "0" ]; then
filtered="$filtered
$dir"
fi
done
matching_dirs=$(printf '%s' "$filtered" | sed '/^$/d')
fi
fi
[ -z "$matching_dirs" ] && return
printf '%s\n' "$matching_dirs" \
| sed "s|^\./|${BASE_PKG}/|" \
| tr '\n' ' '
}
# Discover all unique values for an annotation key.
# Usage: discover_values "resource"
# Returns: newline-separated list of values
discover_values() {
annotation_key="$1"
grep -roh "//testacc:${annotation_key}=[a-z0-9_]*" ./fwprovider/ 2>/dev/null \
| sed "s|//testacc:${annotation_key}=||" \
| sort -u
}
# Validate that all acceptance test files have tier annotations.
# Warns about files that would be missed by --tier all.
validate_annotations() {
missing=$(find ./fwprovider -name '*_test.go' -exec grep -l '//go:build acceptance\|//go:build all' {} \; 2>/dev/null \
| while read -r f; do grep -q '//testacc:tier=' "$f" || echo "$f"; done)
if [ -n "$missing" ]; then
printf 'Warning: acceptance test files without tier annotations (missed by --tier):\n' >&2
printf '%s\n' "$missing" >&2
fi
# Check for unknown tier values
unknown_tiers=""
for t in $(discover_values "tier"); do
case " $KNOWN_TIERS " in
*" $t "*) : ;; # known tier, skip
*) unknown_tiers="$unknown_tiers $t" ;;
esac
done
if [ -n "$unknown_tiers" ]; then
printf 'Warning: unknown tier values found:%s\n' "$unknown_tiers" >&2
fi
}
# Parse arguments
NO_PROXY=""
TEST_NAME=""
GO_FLAGS=""
VERBOSE=""
PARSE_GO_FLAGS=0
EXPECT_PARALLEL=0
EXPECT_PACKAGES=0
EXPECT_TIER=0
EXPECT_RESOURCE=0
TIER=""
RESOURCE=""
for arg in "$@"; do
if [ "$PARSE_GO_FLAGS" = "1" ]; then
GO_FLAGS="${GO_FLAGS} ${arg}"
elif [ "$EXPECT_PARALLEL" = "1" ]; then
PARALLEL="$arg"
EXPECT_PARALLEL=0
elif [ "$EXPECT_PACKAGES" = "1" ]; then
PACKAGES="$arg"
EXPECT_PACKAGES=0
elif [ "$EXPECT_TIER" = "1" ]; then
TIER="$arg"
EXPECT_TIER=0
elif [ "$EXPECT_RESOURCE" = "1" ]; then
RESOURCE="$arg"
EXPECT_RESOURCE=0
elif [ "$arg" = "--" ]; then
PARSE_GO_FLAGS=1
elif [ "$arg" = "--help" ] || [ "$arg" = "-h" ]; then
show_help
exit 0
elif [ "$arg" = "--all" ]; then
TEST_NAME=""
elif [ "$arg" = "--parallel" ]; then
EXPECT_PARALLEL=1
elif [ "$arg" = "--packages" ]; then
EXPECT_PACKAGES=1
elif [ "$arg" = "--tier" ]; then
EXPECT_TIER=1
elif [ "$arg" = "--resource" ]; then
EXPECT_RESOURCE=1
elif [ "$arg" = "--no-proxy" ]; then
NO_PROXY="1"
elif [ "$arg" = "--verbose" ] || [ "$arg" = "--show-command" ]; then
VERBOSE="1"
elif [ -z "$TEST_NAME" ]; then
TEST_NAME="$arg"
else
printf 'Error: Unexpected argument '\''%s'\''\n' "$arg" >&2
printf 'Use '\''./testacc --help'\'' for usage information\n' >&2
exit 1
fi
done
# Validate mutually exclusive options
if [ -n "$TEST_NAME" ] && { [ -n "$TIER" ] || [ -n "$RESOURCE" ]; }; then
printf 'Error: --tier and --resource cannot be combined with a test name\n' >&2
exit 1
fi
if [ -n "$TIER" ] && [ -n "$RESOURCE" ]; then
printf 'Error: --tier and --resource cannot be combined\n' >&2
exit 1
fi
# Strip whitespace from comma-separated tier list
if [ -n "$TIER" ]; then
TIER=$(printf '%s' "$TIER" | tr -d '[:space:]')
fi
# Check for testacc.env
if [ ! -f "testacc.env" ]; then
printf 'Error: testacc.env file not found in current directory\n' >&2
printf '\n' >&2
printf 'Please create testacc.env with the following variables:\n' >&2
printf ' TF_ACC=1\n' >&2
printf ' PROXMOX_VE_API_TOKEN="root@pam!<token>=<value>"\n' >&2
printf ' PROXMOX_VE_ENDPOINT="https://<host>:8006/"\n' >&2
printf ' PROXMOX_VE_SSH_AGENT="true"\n' >&2
printf ' PROXMOX_VE_SSH_USERNAME="root"\n' >&2
printf '\n' >&2
printf 'See CONTRIBUTING.md for more details.\n' >&2
exit 1
fi
# Validate testacc.env
if ! validate_env_file; then
exit 1
fi
# Check if go is available
if ! command -v go >/dev/null 2>&1; then
printf 'Error: go command not found in PATH\n' >&2
exit 1
fi
# Setup NO_PROXY if requested
if [ -n "$NO_PROXY" ]; then
export NO_PROXY="127.0.0.1,localhost,::1"
printf 'Using NO_PROXY=%s\n' "$NO_PROXY" >&2
fi
# Run a go test command, with optional --show-command output.
run_go_test() {
pkg_parallelism="$1"
test_parallelism="$2"
packages="$3"
shift 3
if [ -n "$VERBOSE" ]; then
printf 'Executing: go test -v -count 1 -p %s -parallel %s --tags=acceptance -timeout %s' \
"$pkg_parallelism" "$test_parallelism" "$DEFAULT_TIMEOUT" >&2
if [ -n "$RUN_ARG" ]; then
printf ' %s' "$RUN_ARG" >&2
fi
printf ' %s' "$packages" >&2
if [ -n "$GO_FLAGS" ]; then
printf ' %s' "$GO_FLAGS" >&2
fi
printf '\n' >&2
fi
# shellcheck disable=SC2046,SC2086
TF_ACC=1 env $(grep -v '^#' testacc.env | xargs) \
go test -v -count 1 -p "$pkg_parallelism" -parallel "$test_parallelism" \
--tags=acceptance -timeout "$DEFAULT_TIMEOUT" \
${RUN_ARG} ${packages} ${GO_FLAGS}
}
# Run tests for a single tier.
run_tier() {
tier_name="$1"
tier_p="$2"
tier_pkgs=$(discover_packages "tier" "$tier_name")
if [ -z "$tier_pkgs" ]; then
printf 'No packages found for tier: %s\n' "$tier_name" >&2
return 0
fi
printf '\n=== Tier: %s (packages: -p %s, parallel: %s) ===\n' "$tier_name" "$tier_p" "${PARALLEL:-4}" >&2
run_go_test "$tier_p" "${PARALLEL:-4}" "$tier_pkgs"
}
# Run tests for a resource type.
run_resource() {
resource_name="$1"
resource_pkgs=$(discover_packages "resource" "$resource_name")
if [ -z "$resource_pkgs" ]; then
printf 'No packages found for resource: %s\n' "$resource_name" >&2
printf 'Available resources: %s\n' "$(discover_values resource | tr '\n' ' ')" >&2
return 1
fi
printf '\n=== Resource: %s ===\n' "$resource_name" >&2
run_go_test "${PACKAGES:-1}" "${PARALLEL:-4}" "$resource_pkgs"
}
# Build test command and detect pattern
RUN_ARG=""
IS_PATTERN=0
if [ -n "$TEST_NAME" ]; then
case "$TEST_NAME" in
*'*'*)
RUN_ARG="-run ${TEST_NAME}"
IS_PATTERN=1
printf 'Running tests matching pattern: %s\n' "$TEST_NAME" >&2
;;
*)
RUN_ARG="-run ^${TEST_NAME}\$"
printf 'Running single test: %s\n' "$TEST_NAME" >&2
;;
esac
fi
printf '\n' >&2
# Run tests based on mode
if [ -n "$TIER" ]; then
# Validate annotations before tier-based execution
validate_annotations
TIER_EXIT=0
OLD_IFS="$IFS"
IFS=','
for tier in $TIER; do
IFS="$OLD_IFS"
case "$tier" in
light) run_tier "light" "8" || TIER_EXIT=1 ;;
medium) run_tier "medium" "4" || TIER_EXIT=1 ;;
heavy) run_tier "heavy" "1" || TIER_EXIT=1 ;;
all)
run_tier "light" "8" || TIER_EXIT=1
run_tier "medium" "4" || TIER_EXIT=1
run_tier "heavy" "1" || TIER_EXIT=1
;;
*)
printf 'Error: Unknown tier '\''%s'\''. Use: light, medium, heavy, all\n' "$tier" >&2
exit 1
;;
esac
done
IFS="$OLD_IFS"
exit $TIER_EXIT
elif [ -n "$RESOURCE" ]; then
run_resource "$RESOURCE"
elif [ -n "$TEST_NAME" ]; then
# Single test or pattern (existing behavior)
PACKAGE_PATH=$(find_test_package "$TEST_NAME" "$IS_PATTERN")
printf 'Package: %s\n' "$PACKAGE_PATH" >&2
printf 'Packages: %s, Parallel: %s\n' "${PACKAGES:-1}" "${PARALLEL:-4}" >&2
run_go_test "${PACKAGES:-1}" "${PARALLEL:-4}" "$PACKAGE_PATH"
else
# Default: run all packages (existing behavior)
printf 'Running all acceptance tests\n' >&2
PACKAGE_PATH="${BASE_PKG}/fwprovider/..."
printf 'Package: %s\n' "$PACKAGE_PATH" >&2
printf 'Packages: %s, Parallel: %s\n' "${PACKAGES:-1}" "${PARALLEL:-4}" >&2
run_go_test "${PACKAGES:-1}" "${PARALLEL:-4}" "$PACKAGE_PATH"
fi