Skip to content

Commit

Permalink
Discard broken S3 downloads (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
bradleyayers committed Oct 30, 2023
1 parent 9df04eb commit 475f937
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 7 deletions.
10 changes: 9 additions & 1 deletion lib/backends/s3.bash
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,15 @@ function restore() {
fi

if [[ ! "${BK_AWS_FOUND}" =~ (false) ]]; then
aws s3 cp ${BK_CUSTOM_AWS_ARGS} "s3://${BUCKET}/${TAR_FILE}" .
TMP_FILE="$(mktemp)"
aws s3 cp ${BK_CUSTOM_AWS_ARGS} "s3://${BUCKET}/${TAR_FILE}" "${TMP_FILE}" || s3_download_failed=true
if ${s3_download_failed:-false}; then
echo -e "S3 download failed, soft failing and skipping cache restore..."
return 0
else
mv -f "${TMP_FILE}" "${TAR_FILE}"
fi

[ "${BK_CACHE_SAVE_CACHE}" == "true" ] && cp "${TAR_FILE}" "${BK_CACHE_LOCAL_PATH}/${TAR_FILE}"
tar ${BK_TAR_EXTRACT_ARGS} "${TAR_FILE}" -C .
else
Expand Down
92 changes: 86 additions & 6 deletions tests/command.bats
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ setup() {
}

@test "Pre-command restores cache with basic key" {
stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-key.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key.tar' --profile my-profile : true" \
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key.tar . : echo Copied from S3"
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-key.tar -C . : echo Extracted tar archive"
Expand All @@ -40,6 +45,8 @@ setup() {

unstub aws
unstub tar
unstub mv
unstub mktemp
}

@test "Pre-command restores S3 backed cache using local file" {
Expand Down Expand Up @@ -118,9 +125,15 @@ setup() {
@test "Cache key template evaluation on file" {
CHECKSUM=355831032f586e782b45744f2ed79316cc830244

stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-key-${CHECKSUM}.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar' --profile my-profile : true" \
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar . : echo Copied from S3"
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-key-${CHECKSUM}.tar -C . : echo Extracted tar archive"
Expand All @@ -144,16 +157,24 @@ setup() {
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub mv
unstub aws
unstub tar
}

@test "Cache key template evaluation on dir" {
CHECKSUM=4cfa4e590847976f26d761074e355e4d95fa8107

stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-key-${CHECKSUM}.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar' --profile my-profile : true" \
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar . : echo Copied from S3"
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUM}.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-key-${CHECKSUM}.tar -C . : echo Extracted tar archive"
Expand All @@ -177,16 +198,24 @@ setup() {
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub mv
unstub aws
unstub tar
}

@test "Cache key multi-template evaluation" {
CHECKSUMS=355831032f586e782b45744f2ed79316cc830244-241bc31c8ddc004c48e6d88d7fa51ee981b8ce51

stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-key-${CHECKSUMS}.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key-${CHECKSUMS}.tar' --profile my-profile : true" \
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUMS}.tar . : echo Copied from S3"
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-key-${CHECKSUMS}.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-key-${CHECKSUMS}.tar -C . : echo Extracted tar archive"
Expand All @@ -210,16 +239,24 @@ setup() {
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub mv
unstub aws
unstub tar
}

@test "Cache key template evaluation in middle of key" {
CHECKSUM=355831032f586e782b45744f2ed79316cc830244

stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-${CHECKSUM}-key.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-$CHECKSUM-key.tar' --profile my-profile : true" \
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-$CHECKSUM-key.tar . : echo Copied from S3"
"s3 cp --profile my-profile s3://my-bucket/my-org/my-pipeline/v1-cache-$CHECKSUM-key.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-$CHECKSUM-key.tar -C . : echo Extracted tar archive"
Expand All @@ -243,6 +280,8 @@ setup() {
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub mv
unstub aws
unstub tar
}
Expand Down Expand Up @@ -271,9 +310,15 @@ setup() {

@test "S3 arguments are passed through to copy command" {

stub mktemp \
" : echo '/tmp/tempfile'"

stub mv \
"-f /tmp/tempfile v1-cache-key.tar : true"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key.tar' --profile my-profile : true" \
"s3 cp --profile my-profile --acl bucket-owner-full-control s3://my-bucket/my-org/my-pipeline/v1-cache-key.tar . : echo Copied from S3"
"s3 cp --profile my-profile --acl bucket-owner-full-control s3://my-bucket/my-org/my-pipeline/v1-cache-key.tar /tmp/tempfile : echo Copied from S3"

stub tar \
"-xf v1-cache-key.tar -C . : echo Extracted tar archive"
Expand All @@ -299,6 +344,41 @@ setup() {
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub mv
unstub aws
unstub tar
}

@test "S3 download errors cause soft failure" {

stub mktemp \
" : echo '/tmp/tempfile'"

stub aws \
"s3api head-object --bucket my-bucket --key 'my-org/my-pipeline/v1-cache-key.tar' --profile my-profile : true" \
"s3 cp --profile my-profile --acl bucket-owner-full-control s3://my-bucket/my-org/my-pipeline/v1-cache-key.tar /tmp/tempfile : false"

export BUILDKITE_ORGANIZATION_SLUG="my-org"
export BUILDKITE_PIPELINE_SLUG="my-pipeline"
export BUILDKITE_PLUGIN_CACHE_S3_BUCKET="my-bucket"
export BUILDKITE_PLUGIN_CACHE_S3_PROFILE="my-profile"
export BUILDKITE_PLUGIN_CACHE_S3_ARGS="--acl bucket-owner-full-control"
export BUILDKITE_PLUGIN_CACHE_BACKEND="s3"
export BUILDKITE_PLUGIN_CACHE_KEY="v1-cache-key"

run "$PWD/hooks/pre-command"
assert_success
assert_output --partial "S3 download failed"

unset BUILDKITE_PLUGIN_CACHE_KEY
unset BUILDKITE_PLUGIN_CACHE_BACKEND
unset BUILDKITE_PLUGIN_CACHE_S3_PROFILE
unset BUILDKITE_PLUGIN_CACHE_S3_ARGS
unset BUILDKITE_PLUGIN_CACHE_S3_BUCKET
unset BUILDKITE_PIPELINE_SLUG
unset BUILDKITE_ORGANIZATION_SLUG

unstub mktemp
unstub aws
}

0 comments on commit 475f937

Please sign in to comment.