2727# --fixture <name> (default: mp4-h264-sdr)
2828# --chunk-counts <list> (default: 2,4,8)
2929# --psnr-threshold <db> (default: fixture meta.json minPsnr)
30- # --stack-name <name> (default: hyperframes-lambda-smoke-<timestamp >)
30+ # --stack-name <name> (default: hyperframes-lambda-smoke-<unique-run-id >)
3131# --region <region> (default: $AWS_REGION or us-east-1)
3232# --profile <name> (default: $AWS_PROFILE, otherwise the AWS
3333# default profile resolution chain)
@@ -78,7 +78,8 @@ CHUNK_COUNTS="${CHUNK_COUNTS:-2,4,8}"
7878# calibrated for that content/runtime boundary. Override it via
7979# --psnr-threshold (or PSNR_THRESHOLD) for a stricter experiment.
8080PSNR_THRESHOLD=" ${PSNR_THRESHOLD-} "
81- STACK_NAME=" ${STACK_NAME:- hyperframes-lambda-smoke-$(date +% s)} "
81+ SMOKE_RUN_ID=" ${HYPERFRAMES_SMOKE_RUN_ID:- $(hf_new_smoke_run_id)} "
82+ STACK_NAME=" ${STACK_NAME:- hyperframes-lambda-smoke-${SMOKE_RUN_ID} } "
8283AWS_REGION=" ${AWS_REGION:- us-east-1} "
8384AWS_PROFILE=" ${AWS_PROFILE:- } "
8485PLAN_PROTOCOL=" ${PLAN_PROTOCOL:- v1} "
@@ -106,7 +107,7 @@ Flags:
106107 --fixture <name> fixture under packages/producer/tests/distributed/ (default: mp4-h264-sdr)
107108 --chunk-counts <list> comma-separated chunk counts to benchmark (default: 2,4,8)
108109 --psnr-threshold <db> PSNR floor (default: fixture meta.json minPsnr)
109- --stack-name <name> SAM stack name (default: hyperframes-lambda-smoke-<timestamp >)
110+ --stack-name <name> SAM stack name (default: hyperframes-lambda-smoke-<unique-run-id >)
110111 --region <region> AWS region (default: $AWS_REGION or us-east-1)
111112 --profile <name> AWS profile (default: $AWS_PROFILE)
112113 --plan-protocol <v1|v2|both> plan transport(s) to compare (default: v1)
@@ -241,42 +242,57 @@ cleanup_and_exit() {
241242 else
242243 echo " → Tearing down stack $STACK_NAME "
243244 local cleanup_identity_ok=true
245+ local stack_cleanup_allowed=false
246+ local ownership_status=" "
244247 local discovery_errors=()
245248 if ! aws sts get-caller-identity > /dev/null; then
246249 cleanup_identity_ok=false
247250 echo " ERROR: AWS identity check failed before cleanup; absence cannot be trusted" >&2
248251 fi
249- local discovered
250- if discovered=$( hf_discover_stack_resources " $STACK_NAME " ) ; then
251- if [ -z " $BUCKET " ]; then
252- BUCKET=$( jq -r ' .renderBucket' <<< " $discovered" )
252+ if [ " $cleanup_identity_ok " = true ]; then
253+ if ownership_status=$( hf_stack_ownership_status " $STACK_NAME " " $SMOKE_RUN_ID " ) ; then
254+ if [ " $ownership_status " = " owned" ]; then
255+ stack_cleanup_allowed=true
256+ else
257+ echo " → Stack is absent; skipping stack-scoped destructive cleanup"
258+ fi
259+ else
260+ discovery_errors+=(" verification-error:cloudformation-stack-ownership" )
253261 fi
254- if [ -z " $STATE_MACHINE_ARN " ]; then
255- STATE_MACHINE_ARN=$( jq -r ' .stateMachineArn' <<< " $discovered" )
256- fi
257- else
258- discovery_errors+=(" verification-error:cloudformation-resource-discovery" )
259262 fi
260- if [ -n " $BUCKET " ]; then
261- if ! hf_delete_s3_bucket_completely " $BUCKET " ; then
262- echo " WARN: failed to purge/delete retained render bucket s3://$BUCKET " >&2
263+ if [ " $stack_cleanup_allowed " = true ]; then
264+ local discovered
265+ if discovered=$( hf_discover_stack_resources " $STACK_NAME " ) ; then
266+ if [ -z " $BUCKET " ]; then
267+ BUCKET=$( jq -r ' .renderBucket' <<< " $discovered" )
268+ fi
269+ if [ -z " $STATE_MACHINE_ARN " ]; then
270+ STATE_MACHINE_ARN=$( jq -r ' .stateMachineArn' <<< " $discovered" )
271+ fi
272+ else
273+ discovery_errors+=(" verification-error:cloudformation-resource-discovery" )
263274 fi
264- fi
265- if ! (cd " $SAM_DIR " && sam delete \
266- --stack-name " $STACK_NAME " \
267- --region " $AWS_REGION " \
268- --no-prompts); then
269- echo " WARN: sam delete failed for $STACK_NAME " >&2
270- fi
271- if ! aws cloudformation wait stack-delete-complete --stack-name " $STACK_NAME " ; then
272- echo " WARN: CloudFormation did not confirm stack deletion for $STACK_NAME " >&2
273- fi
274- if aws logs describe-log-groups \
275- --log-group-name-prefix " /aws/lambda/${PROJECT_NAME} -render" \
276- --query " logGroups[?logGroupName=='/aws/lambda/${PROJECT_NAME} -render'].logGroupName" \
277- --output text | grep -q . ; then
278- if ! aws logs delete-log-group --log-group-name " /aws/lambda/${PROJECT_NAME} -render" ; then
279- echo " WARN: failed to delete Lambda log group" >&2
275+ if [ -n " $BUCKET " ]; then
276+ if ! hf_delete_s3_bucket_completely " $BUCKET " ; then
277+ echo " WARN: failed to purge/delete retained render bucket s3://$BUCKET " >&2
278+ fi
279+ fi
280+ if ! (cd " $SAM_DIR " && sam delete \
281+ --stack-name " $STACK_NAME " \
282+ --region " $AWS_REGION " \
283+ --no-prompts); then
284+ echo " WARN: sam delete failed for $STACK_NAME " >&2
285+ fi
286+ if ! aws cloudformation wait stack-delete-complete --stack-name " $STACK_NAME " ; then
287+ echo " WARN: CloudFormation did not confirm stack deletion for $STACK_NAME " >&2
288+ fi
289+ if aws logs describe-log-groups \
290+ --log-group-name-prefix " /aws/lambda/${PROJECT_NAME} -render" \
291+ --query " logGroups[?logGroupName=='/aws/lambda/${PROJECT_NAME} -render'].logGroupName" \
292+ --output text | grep -q . ; then
293+ if ! aws logs delete-log-group --log-group-name " /aws/lambda/${PROJECT_NAME} -render" ; then
294+ echo " WARN: failed to delete Lambda log group" >&2
295+ fi
280296 fi
281297 fi
282298 if [ -n " $SAM_DEPLOY_BUCKET " ]; then
@@ -382,18 +398,25 @@ if ! aws sts get-caller-identity --output text >/dev/null 2>&1; then
382398 exit 1
383399fi
384400
385- # This check runs before cleanup is armed or any resource is created. A name
386- # collision must never route through cleanup, because cleanup is destructive.
401+ # This check runs before cleanup is armed or any resource is created.
387402echo " → Pre-flight: proving exact AWS resource names are unused"
388403if ! hf_assert_deploy_isolation " $STACK_NAME " " $PROJECT_NAME " ; then
389404 echo " ERROR: refusing to reuse or clean resources not created by this run." >&2
390405 exit 1
391406fi
392407
393- # From this point onward, unexpected failures must tear down resources created
394- # by this exact, preflight-isolated run.
408+ # Arm cleanup before atomically reserving the stack name. If another smoke run
409+ # wins the create-stack race, ownership verification prevents this run from
410+ # touching it. If this run wins, every later destructive action requires the
411+ # same ownership tag.
395412trap ' cleanup_and_exit $?' EXIT
396413
414+ echo " → Pre-flight: atomically reserving stack name for this smoke run"
415+ if ! hf_reserve_smoke_stack " $STACK_NAME " " $SMOKE_RUN_ID " ; then
416+ echo " ERROR: could not reserve stack name; another run may have won the race." >&2
417+ cleanup_and_exit 1
418+ fi
419+
397420mkdir -p " $ARTIFACT_DIR /renders"
398421
399422# ── 1. Build the handler ZIP ──────────────────────────────────────────────
@@ -419,7 +442,7 @@ echo "→ SAM deploy (stack=$STACK_NAME, region=$AWS_REGION)"
419442# at its default makes concurrent smoke stacks overwrite/collide. A dedicated
420443# SAM bucket also lets teardown remove every object created by this run.
421444ACCOUNT_ID=$( aws sts get-caller-identity --query Account --output text)
422- SAM_DEPLOY_BUCKET=" hf-sam- ${ ACCOUNT_ID} - ${ AWS_REGION} - $( date +%s ) - $$ "
445+ SAM_DEPLOY_BUCKET=$( hf_sam_deploy_bucket_name " $ ACCOUNT_ID" " $ AWS_REGION" " $SMOKE_RUN_ID " )
423446if [ " $AWS_REGION " = " us-east-1" ]; then
424447 aws s3api create-bucket --bucket " $SAM_DEPLOY_BUCKET " > /dev/null
425448else
@@ -434,6 +457,7 @@ if ! (cd "$SAM_DIR" && sam deploy \
434457 --capabilities CAPABILITY_IAM \
435458 --no-confirm-changeset \
436459 --no-fail-on-empty-changeset \
460+ --tags " HyperframesSmokeRun=$SMOKE_RUN_ID " \
437461 --parameter-overrides \
438462 " ProjectName=$PROJECT_NAME " \
439463 ChromeSource=sparticuz \
0 commit comments