-
Notifications
You must be signed in to change notification settings - Fork 0
test: isolate the suite per worker and enforce two conventions mechanically #86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
fac06cf
build(devcontainer): bring the devcontainer subsystem into this PR
marcinpsk 7d7fed2
test: give every pytest worker private databases and one plugin
marcinpsk 56a9ad1
test: build the repeated DCIM fixtures through shared helpers
marcinpsk 4018aa1
test: enforce the family seam and the comment-block rule mechanically
marcinpsk 0135ded
build(devcontainer): stop the container caching bytecode into the hos…
marcinpsk 45e205d
test(devcontainer): render the compose files a recreate actually uses
marcinpsk 674e096
fix: drop migration dependencies on a squashed-away dcim node
marcinpsk ba8aba4
test: report every dangling migration dependency, not just the first
marcinpsk 9cb5640
build(devcontainer): install ripgrep for agent searches
marcinpsk 07b6880
fix: close four review findings in the isolation and guard tests
marcinpsk aa80ef8
fix: match pytest options written as --option=value
marcinpsk 8ffde69
fix: set the worker's Redis targets in the settings shim, not only in…
marcinpsk 6443bf0
fix(tests): preserve Redis credentials without passwords
marcinpsk c7bbfab
test: write the base-row collision setup as an out-of-band rename
marcinpsk 6313c80
fix(tests): preserve targets and strengthen repository guards
marcinpsk 1582a59
fix(tests): distinguish command prefixes and file modes
marcinpsk ce415c9
fix(tests): detect pytest in chained shell commands
marcinpsk 4bad0da
fix(tests): inspect workflow run commands for pytest
marcinpsk 86f9d31
fix(tests): classify pytest commands with shell syntax
marcinpsk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| #!/bin/bash | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com> | ||
|
|
||
| # Populate COMPOSE_FILES with the `-f` arguments a real recreate would use. | ||
| # | ||
| # The override is untracked and per-developer, but Docker applies it to every recreate. A check that | ||
| # renders only the base file cannot see a value the override replaces, so it would pass while the | ||
| # container it protects comes up wrong. | ||
| compose_file_args() { | ||
| local root="$1" | ||
| local override="$root/.devcontainer/docker-compose.override.yml" | ||
|
|
||
| COMPOSE_FILES=(-f "$root/.devcontainer/docker-compose.yml") | ||
| if [ -f "$override" ]; then | ||
| COMPOSE_FILES+=(-f "$override") | ||
| fi | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #!/bin/bash | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com> | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" | ||
| # shellcheck source=.devcontainer/scripts/tests/lib.sh | ||
| source "$(dirname "$0")/lib.sh" | ||
| compose_file_args "$REPO_ROOT" | ||
|
|
||
| # The container runs as root and mounts the host checkout, so any bytecode Python caches lands in | ||
| # the developer's tree owned by root. Those files can block `git worktree remove` and host tooling. | ||
| docker compose "${COMPOSE_FILES[@]}" config --format json | python3 -c " | ||
| import json | ||
| import sys | ||
|
|
||
| configuration = json.load(sys.stdin) | ||
| services = configuration.get('services', {}) | ||
|
|
||
| failures = [] | ||
| for name, service in services.items(): | ||
| # Only services that mount the host checkout can write into it. | ||
| mounts = service.get('volumes') or [] | ||
| if not any(str(mount.get('target', '')).startswith('/workspaces') for mount in mounts): | ||
| continue | ||
| value = (service.get('environment') or {}).get('PYTHONDONTWRITEBYTECODE') | ||
| if str(value) != '1': | ||
| failures.append(f'{name} mounts the checkout but sets PYTHONDONTWRITEBYTECODE={value!r}') | ||
|
|
||
| if failures: | ||
| for failure in failures: | ||
| print(f'FAIL: {failure}', file=sys.stderr) | ||
| print( | ||
| 'Root-owned .pyc files would accumulate in the host tree. ' | ||
| 'Set PYTHONDONTWRITEBYTECODE: \"1\" on that service.', | ||
| file=sys.stderr, | ||
| ) | ||
| raise SystemExit(1) | ||
|
|
||
| if not services: | ||
| print('FAIL: the compose file declares no services', file=sys.stderr) | ||
| raise SystemExit(1) | ||
|
|
||
| print('Bytecode-write check passed (no checkout-mounting service caches bytecode)') | ||
| " |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| #!/bin/bash | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com> | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" | ||
| # shellcheck source=.devcontainer/scripts/tests/lib.sh | ||
| source "$(dirname "$0")/lib.sh" | ||
| compose_file_args "$REPO_ROOT" | ||
| CONTAINER_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" | ||
| HOST_CA_BUNDLE="/host-only/ca.pem" | ||
|
|
||
| config="$({ | ||
| REQUESTS_CA_BUNDLE="$HOST_CA_BUNDLE" \ | ||
| SSL_CERT_FILE="$HOST_CA_BUNDLE" \ | ||
| CURL_CA_BUNDLE="$HOST_CA_BUNDLE" \ | ||
| docker compose "${COMPOSE_FILES[@]}" config | ||
| })" | ||
|
|
||
| # Compare the rendered value as a string. A grep pattern would read every "." in a certificate | ||
| # path as a wildcard, so a wrong path such as ca-certificatesXcrt would satisfy the check. | ||
| for variable in REQUESTS_CA_BUNDLE SSL_CERT_FILE CURL_CA_BUNDLE; do | ||
| value="$(awk -v key="$variable:" '$1 == key { print $2; exit }' <<< "$config")" | ||
| value="${value%\"}" | ||
| value="${value#\"}" | ||
| if [ "$value" != "$CONTAINER_CA_BUNDLE" ]; then | ||
| echo "FAIL: $variable is '$value', not the container trust store $CONTAINER_CA_BUNDLE" >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| if grep -qF "$HOST_CA_BUNDLE" <<< "$config"; then | ||
| echo "FAIL: a host CA path leaked into the container configuration" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| echo "Container CA environment check passed" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| #!/bin/bash | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com> | ||
|
|
||
| set -eo pipefail | ||
|
|
||
| REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" | ||
| TEST_DIR="$(mktemp -d)" | ||
| trap 'rm -rf "$TEST_DIR"' EXIT | ||
| export PYTEST_ARGV="$TEST_DIR/argv" | ||
|
|
||
| source() { | ||
| if [ "$1" = /opt/netbox/venv/bin/activate ]; then | ||
| return 0 | ||
| fi | ||
| builtin source "$@" | ||
| } | ||
| source "$REPO_ROOT/.devcontainer/scripts/load-aliases.sh" | ||
| cat > "$TEST_DIR/pytest" <<'STUB' | ||
| #!/bin/bash | ||
| printf '%s\n' "$@" > "$PYTEST_ARGV" | ||
| STUB | ||
| chmod +x "$TEST_DIR/pytest" | ||
| export PATH="$TEST_DIR:$PATH" | ||
|
|
||
| netbox-test | ||
| printf '%s\n' netbox_interface_name_rules > "$TEST_DIR/expected" | ||
| diff -u "$TEST_DIR/expected" "$PYTEST_ARGV" | ||
|
|
||
| netbox-test netbox_interface_name_rules/tests/test_rules.py -k 'a test name' | ||
| printf '%s\n' netbox_interface_name_rules/tests/test_rules.py -k 'a test name' > "$TEST_DIR/expected" | ||
| diff -u "$TEST_DIR/expected" "$PYTEST_ARGV" | ||
| printf '%s\n' 'NetBox test target check passed' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #!/bin/bash | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com> | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| REPO_ROOT="$(cd "$(dirname "$0")/../../.." && pwd)" | ||
| # shellcheck source=.devcontainer/scripts/tests/lib.sh | ||
| source "$(dirname "$0")/lib.sh" | ||
| compose_file_args "$REPO_ROOT" | ||
|
|
||
| if [ -n "${NETWORK_PINS_CONFIG:-}" ]; then | ||
| config="$(cat -- "$NETWORK_PINS_CONFIG")" | ||
| else | ||
| config="$(docker compose "${COMPOSE_FILES[@]}" config)" | ||
| fi | ||
|
|
||
| mapfile -t ranges < <(sed -n 's/^[[:space:]]*ip_range:[[:space:]]*"\{0,1\}\([^"]*\)"\{0,1\}$/\1/p' <<< "$config") | ||
| if [ "${#ranges[@]}" -eq 0 ]; then | ||
| echo "FAIL: the default network declares no ip_range, so Docker may hand a pinned address to another service" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ "${#ranges[@]}" -gt 1 ]; then | ||
| echo "FAIL: expected one ip_range, found ${#ranges[@]}" >&2 | ||
| exit 1 | ||
| fi | ||
| ip_range="${ranges[0]}" | ||
|
|
||
| mapfile -t pinned < <(sed -n 's/^[[:space:]]*ipv4_address:[[:space:]]*"\{0,1\}\([^"]*\)"\{0,1\}$/\1/p' <<< "$config") | ||
| if [ "${#pinned[@]}" -eq 0 ]; then | ||
| echo "FAIL: no service pins an ipv4_address, so this check has nothing to protect" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Every pinned address must sit outside the pool Docker assigns from. | ||
| for address in "${pinned[@]}"; do | ||
| verdict="$(python3 -c ' | ||
| import ipaddress, sys | ||
| print("inside" if ipaddress.ip_address(sys.argv[1]) in ipaddress.ip_network(sys.argv[2]) else "outside") | ||
| ' "$address" "$ip_range")" | ||
| if [ "$verdict" = "inside" ]; then | ||
| echo "FAIL: pinned address $address lies inside the dynamic range $ip_range" >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| echo "Network pin check passed (${#pinned[@]} pinned addresses outside $ip_range)" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.