runner fix
This commit is contained in:
@@ -62,6 +62,9 @@ pnpm infrastructure:smoke
|
|||||||
The smoke test verifies PostgreSQL password authentication and authenticated S3 list, put, get,
|
The smoke test verifies PostgreSQL password authentication and authenticated S3 list, put, get,
|
||||||
head, and delete operations. It also proves invalid database passwords, anonymous object access,
|
head, and delete operations. It also proves invalid database passwords, anonymous object access,
|
||||||
and invalid S3 signatures are rejected. Its containers, network, and volumes are removed on exit.
|
and invalid S3 signatures are rejected. Its containers, network, and volumes are removed on exit.
|
||||||
|
When the smoke script itself runs in a Docker-based CI job, it temporarily joins that job container
|
||||||
|
to the isolated Compose network and reaches object storage by its service name. Direct host runs
|
||||||
|
continue to use Docker-assigned random ports published only on loopback.
|
||||||
|
|
||||||
PostgreSQL and the S3 endpoint bind to `127.0.0.1` only. Compose uses persistent named volumes;
|
PostgreSQL and the S3 endpoint bind to `127.0.0.1` only. Compose uses persistent named volumes;
|
||||||
`infrastructure:down` preserves data. The S3 service creates the configured development bucket
|
`infrastructure:down` preserves data. The S3 service creates the configured development bucket
|
||||||
|
|||||||
@@ -50,6 +50,18 @@ compose=(
|
|||||||
--env-file .env.example
|
--env-file .env.example
|
||||||
--file infrastructure/compose.yaml
|
--file infrastructure/compose.yaml
|
||||||
)
|
)
|
||||||
|
running_in_container=false
|
||||||
|
current_container=""
|
||||||
|
compose_network=""
|
||||||
|
connected_to_compose_network=false
|
||||||
|
if [[ -f /.dockerenv ]]; then
|
||||||
|
running_in_container=true
|
||||||
|
if [[ -z "${HOSTNAME:-}" ]]; then
|
||||||
|
echo "HOSTNAME is required when the smoke test runs inside a Docker container." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
current_container="$HOSTNAME"
|
||||||
|
fi
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
local exit_status=$?
|
local exit_status=$?
|
||||||
@@ -58,6 +70,17 @@ cleanup() {
|
|||||||
if ((exit_status != 0)); then
|
if ((exit_status != 0)); then
|
||||||
"${compose[@]}" logs --no-color >&2 || true
|
"${compose[@]}" logs --no-color >&2 || true
|
||||||
fi
|
fi
|
||||||
|
if [[ "$connected_to_compose_network" == "true" ]]; then
|
||||||
|
if ! cleanup_output="$(
|
||||||
|
docker network disconnect "$compose_network" "$current_container" 2>&1
|
||||||
|
)"; then
|
||||||
|
echo "Infrastructure smoke network cleanup failed:" >&2
|
||||||
|
echo "$cleanup_output" >&2
|
||||||
|
if ((exit_status == 0)); then
|
||||||
|
exit_status=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
if ! cleanup_output="$(
|
if ! cleanup_output="$(
|
||||||
"${compose[@]}" down --volumes --remove-orphans --timeout 10 2>&1
|
"${compose[@]}" down --volumes --remove-orphans --timeout 10 2>&1
|
||||||
)"; then
|
)"; then
|
||||||
@@ -110,6 +133,48 @@ if "${compose[@]}" exec -T \
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "$running_in_container" == "true" ]]; then
|
||||||
|
object_storage_container="$("${compose[@]}" ps -q object-storage)"
|
||||||
|
if [[ -z "$object_storage_container" ]]; then
|
||||||
|
echo "Compose did not return the object-storage container ID." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
network_output="$(
|
||||||
|
docker inspect \
|
||||||
|
--format '{{range $networkName, $_ := .NetworkSettings.Networks}}{{println $networkName}}{{end}}' \
|
||||||
|
"$object_storage_container"
|
||||||
|
)"
|
||||||
|
object_storage_networks=()
|
||||||
|
while IFS= read -r network_name; do
|
||||||
|
if [[ -n "$network_name" ]]; then
|
||||||
|
object_storage_networks+=("$network_name")
|
||||||
|
fi
|
||||||
|
done <<<"$network_output"
|
||||||
|
if ((${#object_storage_networks[@]} != 1)); then
|
||||||
|
echo "Expected object-storage to use exactly one Compose network." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
compose_network="${object_storage_networks[0]}"
|
||||||
|
|
||||||
|
current_network_output="$(
|
||||||
|
docker inspect \
|
||||||
|
--format '{{range $networkName, $_ := .NetworkSettings.Networks}}{{println $networkName}}{{end}}' \
|
||||||
|
"$current_container"
|
||||||
|
)"
|
||||||
|
already_connected=false
|
||||||
|
while IFS= read -r network_name; do
|
||||||
|
if [[ "$network_name" == "$compose_network" ]]; then
|
||||||
|
already_connected=true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done <<<"$current_network_output"
|
||||||
|
if [[ "$already_connected" != "true" ]]; then
|
||||||
|
docker network connect "$compose_network" "$current_container"
|
||||||
|
connected_to_compose_network=true
|
||||||
|
fi
|
||||||
|
s3_endpoint="http://object-storage:8333"
|
||||||
|
else
|
||||||
s3_binding="$("${compose[@]}" port object-storage 8333)"
|
s3_binding="$("${compose[@]}" port object-storage 8333)"
|
||||||
s3_port="${s3_binding##*:}"
|
s3_port="${s3_binding##*:}"
|
||||||
if [[ ! "$s3_port" =~ ^[0-9]+$ ]]; then
|
if [[ ! "$s3_port" =~ ^[0-9]+$ ]]; then
|
||||||
@@ -117,6 +182,7 @@ if [[ ! "$s3_port" =~ ^[0-9]+$ ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
s3_endpoint="http://127.0.0.1:$s3_port"
|
s3_endpoint="http://127.0.0.1:$s3_port"
|
||||||
|
fi
|
||||||
signed_curl=(
|
signed_curl=(
|
||||||
curl
|
curl
|
||||||
--silent
|
--silent
|
||||||
|
|||||||
@@ -79,6 +79,25 @@ describe("development infrastructure", () => {
|
|||||||
expect(infrastructureCommands).toContain("bash scripts/smoke-infrastructure.sh");
|
expect(infrastructureCommands).toContain("bash scripts/smoke-infrastructure.sh");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("routes containerized S3 smoke checks through the isolated Compose network", async () => {
|
||||||
|
const source = await readFile(
|
||||||
|
path.join(repositoryRoot, "scripts", "smoke-infrastructure.sh"),
|
||||||
|
"utf8",
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(source).toContain("[[ -f /.dockerenv ]]");
|
||||||
|
expect(source).toContain(`object_storage_container="$("\${compose[@]}" ps -q object-storage)"`);
|
||||||
|
expect(source).toContain("docker inspect");
|
||||||
|
expect(source).toContain('docker network connect "$compose_network" "$current_container"');
|
||||||
|
expect(source).toContain('docker network disconnect "$compose_network" "$current_container"');
|
||||||
|
expect(source).toContain('s3_endpoint="http://object-storage:8333"');
|
||||||
|
expect(source).toContain('s3_endpoint="http://127.0.0.1:$s3_port"');
|
||||||
|
expect(source).not.toContain("0.0.0.0:${S3_PORT");
|
||||||
|
expect(source.indexOf("docker network disconnect")).toBeLessThan(
|
||||||
|
source.indexOf(`"\${compose[@]}" down`),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("includes every official platform layer in the workspace", async () => {
|
it("includes every official platform layer in the workspace", async () => {
|
||||||
const source = await readFile(path.join(repositoryRoot, "pnpm-workspace.yaml"), "utf8");
|
const source = await readFile(path.join(repositoryRoot, "pnpm-workspace.yaml"), "utf8");
|
||||||
const workspace = parse(source) as WorkspaceDocument;
|
const workspace = parse(source) as WorkspaceDocument;
|
||||||
|
|||||||
Reference in New Issue
Block a user