Skip to content

Instantly share code, notes, and snippets.

@ExternalReality
Created June 15, 2020 16:11
Show Gist options
  • Save ExternalReality/19b311c93a87ff7b4ecdfcb3f23bed41 to your computer and use it in GitHub Desktop.
Save ExternalReality/19b311c93a87ff7b4ecdfcb3f23bed41 to your computer and use it in GitHub Desktop.
version: 2.1
orbs:
aws-cli: circleci/aws-cli@1.1.0
dynamic-split:
orbs:
aws-cli: circleci/aws-cli@1.1.0
commands:
test:
description: Run test with dynamic splitting algorithm
parameters:
split-command:
type: string
test-command:
type: string
steps:
- create-queue
- populate-queue:
split-command: <<parameters.split-command>>
- get-queue-url
- run-tests:
test-command: <<parameters.test-command>>
- send-done-message
- delete-queue
create-queue:
description: Create a FIFO queue to distribute test work.
steps:
- aws-cli/setup
- run:
name: create work queue
command: |
echo 'export queue_name=queue-${CIRCLE_JOB}-${CIRCLE_WORKFLOW_ID}.fifo' >> $BASH_ENV
echo 'export done_queue_name=done-queue-${CIRCLE_JOB}-${CIRCLE_WORKFLOW_ID}.fifo' >> $BASH_ENV
if [ $CIRCLE_NODE_INDEX -eq 0 ]
then
echo 'export queue_url=$(aws sqs create-queue --queue-name $queue_name --attributes \
'FifoQueue=true,ContentBasedDeduplication=true' | jq -r ".QueueUrl")' >> $BASH_ENV
echo 'export done_queue_url=$(aws sqs create-queue --queue-name $done_queue_name --attributes \
'FifoQueue=true,ContentBasedDeduplication=true' | jq -r ".QueueUrl")' >> $BASH_ENV
fi
populate-queue:
description: Populate the test queue with work
parameters:
split-command:
type: string
steps:
- run:
name: populate test queue
command: |
if [ $CIRCLE_NODE_INDEX -eq 0 ]
then
# glob out targets in a format `cargo test` understands
test_targets=$(<<parameters.split-command>>)
# send off batches of messages by 10
xargs -n 10 \<<<$test_targets | while read x
do
echo $x
echo $x | jq -nR '( input | split(" ") ) as $vals | $vals | to_entries | map({"Id": (.key|tostring), "MessageGroupId": (.key|tostring), "MessageBody": .value })' > sqs_batch_message.json
aws sqs send-message-batch --queue-url $queue_url --entries file://sqs_batch_message.json
done
fi
get-queue-url:
description: Get the queue url for this test run
steps:
- run:
name: get queue url
command: |
if [ $CIRCLE_NODE_INDEX -gt 0 ]
then
echo $queue_name
echo $done_queue_name
queue_url=''
while [ -z $queue_url ]; do
echo 'export queue_url=$(aws sqs get-queue-url --queue-name $queue_name | jq -r ".QueueUrl")' >> $BASH_ENV
echo "queue_url = $queue_url"
source $BASH_ENV
done
done_queue_url=''
while [ -z $done_queue_url ]; do
echo 'export done_queue_url=$(aws sqs get-queue-url --queue-name $done_queue_name | jq -r ".QueueUrl")' >> $BASH_ENV
echo "done_queue_url = $done_queue_url"
source $BASH_ENV
done
fi
delete-queue:
description: cleanup queue resources
steps:
- run:
name: delete test queues
command: |
echo $CIRCLE_NODE_INDEX
if [ $CIRCLE_NODE_INDEX -eq 0 ]
then
COUNTER=0
while [ $COUNTER -lt $(($CIRCLE_NODE_TOTAL - 1)) ]; do
messages=$(aws sqs receive-message --queue-url $done_queue_url --max-number-of-messages 1 --wait-time-seconds 1 | jq -r ".Messages[]")
echo $messages
if [ ! -z "$messages" ]
then
echo "we are here"
receipt_handle=$(echo $messages | jq -r ".ReceiptHandle")
aws sqs delete-message --queue-url $done_queue_url --receipt-handle $receipt_handle
let COUNTER=COUNTER+1
fi
done
aws sqs delete-queue --queue-url $queue_url
aws sqs delete-queue --queue-url $done_queue_url
fi
when: always
run-tests:
description: run tests across nodes
parameters:
test-command:
description: command that is used to run tests
type: string
steps:
- run:
name: run tests across nodes
command: |
COUNTER=0
while [ $COUNTER -lt 3 ]; do
messages=$(aws sqs receive-message --queue-url $queue_url --attribute-names All --message-attribute-names All --max-number-of-messages 1 --wait-time-seconds 1 | jq -r ".Messages[]")
echo $messages
if [ ! -z "$messages" ]
then
current_test=$(echo $messages | jq -r ".Body")
receipt_handle=$(echo $messages | jq -r ".ReceiptHandle")
aws sqs delete-message --queue-url $queue_url --receipt-handle $receipt_handle
echo $current_test
echo current state of counter = $COUNTER
COUNTER=0
echo $current_test | xargs -n 1 -x -I@ << parameters.test-command >>
else
let COUNTER=COUNTER+1
fi
done
send-done-message:
description: Communicate to master node that work is done
steps:
- run:
command: |
if [ $CIRCLE_NODE_INDEX -gt 0 ]
then
echo "sending done message"
aws sqs send-message --queue-url $done_queue_url --message-body $CIRCLE_NODE_INDEX --message-group-id $CIRCLE_NODE_INDEX
fi
when: always
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment