nuthatch/tests/kind/streaming-run.sh

227 lines
7.3 KiB
Shell
Raw Permalink Normal View History

#!/usr/bin/env bash
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
source "$ROOT/tests/kind/lib.sh"
USER_KUBECONFIG_BEFORE="$(user_kubeconfig_digest)"
SUCCEEDED=false
OWNS_FIXTURE=false
APP_IMAGE=nuthatch-streaming:local
cleanup() {
local status=$?
trap - EXIT INT TERM
if [[ "${NUTHATCH_TESTBED_RETAIN:-0}" = 1 ]] && [[ "$SUCCEEDED" != true ]]; then
printf 'retained kubeconfig: %s\n' "$KUBECONFIG_PATH"
printf 'retained context: %s\n' "$CONTEXT"
exit "$status"
fi
if [[ "$OWNS_FIXTURE" = true ]]; then
destroy_fixture || status=1
fi
if [[ "$(user_kubeconfig_digest)" != "$USER_KUBECONFIG_BEFORE" ]]; then
printf 'user kubeconfig changed unexpectedly\n' >&2
status=1
fi
exit "$status"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
render_application() {
local lane="$1"
local profile_file="$2"
local rate="$3"
local burst="$4"
local pg_conn
local redis_url
local oidc_issuer
local oidc_client_id
local oidc_additional_audiences
local oidc_client_secret
local s3_endpoint
local s3_region
local s3_bucket
local s3_access_key
local s3_secret_key
pg_conn="$(sed -n 's/^NUTHATCH_PG_CONN=//p' "$profile_file")"
redis_url="$(sed -n 's/^NUTHATCH_REDIS_URL=//p' "$profile_file")"
oidc_issuer="$(sed -n 's/^NUTHATCH_OIDC_ISSUER=//p' "$profile_file")"
oidc_client_id="$(sed -n 's/^NUTHATCH_OIDC_CLIENT_ID=//p' "$profile_file")"
oidc_additional_audiences="$(
sed -n 's/^NUTHATCH_OIDC_ADDITIONAL_AUDIENCES=//p' "$profile_file"
)"
oidc_client_secret="$(<"$profile_file.oidc-secret")"
s3_endpoint="$(sed -n 's/^NUTHATCH_S3_ENDPOINT=//p' "$profile_file")"
s3_region="$(sed -n 's/^NUTHATCH_S3_REGION=//p' "$profile_file")"
s3_bucket="$(sed -n 's/^NUTHATCH_S3_BUCKET=//p' "$profile_file")"
s3_access_key="$(sed -n 's/^NUTHATCH_S3_ACCESS_KEY=//p' "$profile_file")"
s3_secret_key="$(sed -n 's/^NUTHATCH_S3_SECRET_KEY=//p' "$profile_file")"
sed \
-e "s|@@LANE@@|$lane|g" \
-e "s|@@APP_IMAGE@@|$APP_IMAGE|g" \
-e "s|@@PG_CONN@@|$pg_conn|g" \
-e "s|@@REDIS_URL@@|$redis_url|g" \
-e "s|@@OIDC_ISSUER@@|$oidc_issuer|g" \
-e "s|@@OIDC_CLIENT_ID@@|$oidc_client_id|g" \
-e "s|@@OIDC_ADDITIONAL_AUDIENCES@@|$oidc_additional_audiences|g" \
-e "s|@@OIDC_CLIENT_SECRET@@|$oidc_client_secret|g" \
-e "s|@@S3_ENDPOINT@@|$s3_endpoint|g" \
-e "s|@@S3_REGION@@|$s3_region|g" \
-e "s|@@S3_BUCKET@@|$s3_bucket|g" \
-e "s|@@S3_ACCESS_KEY@@|$s3_access_key|g" \
-e "s|@@S3_SECRET_KEY@@|$s3_secret_key|g" \
"$ROOT/deploy/kubernetes/nuthatch.yaml.in" > "$RUNTIME/streaming-app-$lane.yaml"
sed -i \
"/NUTHATCH_S3_PATH_STYLE/a\\ NUTHATCH_MAX_OBJECT_BYTES: \"201326592\"\\n NUTHATCH_THROTTLE_BYTES_PER_SEC: \"$rate\"\\n NUTHATCH_THROTTLE_BURST_BYTES: \"$burst\"" \
"$RUNTIME/streaming-app-$lane.yaml"
sed -i 's/ replicas: 1/ replicas: 2/' "$RUNTIME/streaming-app-$lane.yaml"
sed -i \
's/limits: {cpu: "2", memory: 512Mi}/limits: {cpu: "2", memory: 128Mi}/' \
"$RUNTIME/streaming-app-$lane.yaml"
sed -i \
'/ envFrom:/i\ env:\n - {name: GHCRTS, value: "-N2 -A1m -M96m"}' \
"$RUNTIME/streaming-app-$lane.yaml"
}
cleanup_application() {
local lane="$1"
kube --namespace "$FIXTURE_NAMESPACE" delete \
"deployment/nuthatch-$lane" \
"service/nuthatch-$lane" \
"configmap/nuthatch-$lane" \
"secret/nuthatch-$lane" \
--ignore-not-found >/dev/null
rm -f "$RUNTIME/streaming-app-$lane.yaml"
}
set_streaming_profile() {
local profile="$1"
local mode="$2"
local throttle_burst=262144
local profile_file="$RUNTIME/$profile.env"
if [[ "$mode" = refill ]]; then
throttle_burst=65536
fi
sed -i '/^NUTHATCH_STREAMING_/d' "$profile_file"
{
printf 'NUTHATCH_STREAMING_MODE=%s\n' "$mode"
printf 'NUTHATCH_STREAMING_LARGE_BYTES=167772160\n'
printf 'NUTHATCH_STREAMING_OVER_LIMIT_BYTES=201326593\n'
printf 'NUTHATCH_STREAMING_THROTTLE_BURST_BYTES=%s\n' "$throttle_burst"
} >> "$profile_file"
kube create configmap "$profile" \
--namespace "$FIXTURE_NAMESPACE" \
--from-env-file="$profile_file" \
--dry-run=client \
--output yaml |
kube apply --filename - >/dev/null
}
run_streaming_job() {
local lane="$1"
local profile="$2"
local mode="$3"
local job="streaming-$mode-$lane"
set_streaming_profile "$profile" "$mode"
render_lane_job \
"$job" \
"$TESTBED/application-probe-job.yaml.in" \
"$APP_IMAGE" \
"$profile"
sed -i \
-e "s|@@LANE@@|$lane|g" \
-e 's|@@COMPONENT@@|streaming|g' \
-e 's|@@PROBE@@|nuthatch-streaming-probe|g' \
-e "s|@@PROBE_ARGS@@|\"$mode\"|g" \
-e 's|@@DEADLINE_SECONDS@@|600|g' \
"$RUNTIME/$job.yaml"
run_job_manifest "$job" "$RUNTIME/$job.yaml"
}
scale_coordination() {
local provider="$1"
local replicas="$2"
kube --namespace "$FIXTURE_NAMESPACE" scale \
"deployment/$provider" \
--replicas="$replicas" >/dev/null
if [[ "$replicas" = 0 ]]; then
kube --namespace "$FIXTURE_NAMESPACE" wait \
--for=delete \
"pod" \
--selector="app=$provider" \
--timeout=120s >/dev/null
else
kube --namespace "$FIXTURE_NAMESPACE" rollout status \
"deployment/$provider" \
--timeout=180s >/dev/null
fi
}
deploy_application() {
local lane="$1"
local profile="$2"
local rate="$3"
local burst="$4"
cleanup_application "$lane"
render_application "$lane" "$RUNTIME/$profile.env" "$rate" "$burst"
kube apply --filename "$RUNTIME/streaming-app-$lane.yaml" >/dev/null
kube --namespace "$FIXTURE_NAMESPACE" rollout status \
"deployment/nuthatch-$lane" --timeout=180s
}
acquire_fixture_lock
OWNS_FIXTURE=true
setup_fixture durable coordination oidc target
source "$RUNTIME/fixture.env"
"$NUTHATCH_REAL_NERDCTL" --namespace "$NERDCTL_NAMESPACE" build \
--file "$ROOT/Dockerfile" \
--target test-runtime \
--tag "$APP_IMAGE" \
"$ROOT"
load_local_image "$APP_IMAGE" "$NERDCTL_NAMESPACE"
while IFS=$'\t' read -r lane coordination oidc target; do
if [[ -n "${NUTHATCH_STREAMING_LANE:-}" ]] &&
[[ "$lane" != "$NUTHATCH_STREAMING_LANE" ]]; then
continue
fi
profile="$(write_lane_profile "$lane" "$coordination" "$oidc" "$target")"
printf 'Running streaming lane %s: coordination=%s oidc=%s target=%s\n' \
"$lane" "$coordination" "$oidc" "$target"
deploy_application "$lane" "$profile" 536870912 536870912
run_streaming_job "$lane" "$profile" large
cleanup_application "$lane"
scale_coordination "$coordination" 0
scale_coordination "$coordination" 1
deploy_application "$lane" "$profile" 1 262144
run_streaming_job "$lane" "$profile" throttle
cleanup_application "$lane"
scale_coordination "$coordination" 0
scale_coordination "$coordination" 1
deploy_application "$lane" "$profile" 1 65536
run_streaming_job "$lane" "$profile" refill
deploy_application "$lane" "$profile" 536870912 536870912
scale_coordination "$coordination" 0
run_streaming_job "$lane" "$profile" unavailable
cleanup_application "$lane"
scale_coordination "$coordination" 1
cleanup_lane_state "$lane" "$coordination" "$oidc" "$target"
for mode in large throttle refill unavailable; do
cleanup_lane_resources "streaming-$mode-$lane" "$profile"
done
if [[ "${NUTHATCH_STREAMING_FIRST_LANE_ONLY:-0}" = 1 ]]; then
break
fi
done < <(expand_fixture_matrix coordination oidc target)
SUCCEEDED=true
printf 'Nuthatch streaming gate passed\n'