Skip to content

Commit 9c7367d

Browse files
committed
change: allow only one integration test run per time
1 parent 131ec2a commit 9c7367d

File tree

2 files changed

+142
-53
lines changed

2 files changed

+142
-53
lines changed

buildspec.yml

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,58 +7,48 @@ phases:
77

88
build:
99
commands:
10-
# run linters
11-
- tox -e flake8,pylint
12-
13-
# run package and docbuild checks
14-
- tox -e twine
15-
- tox -e sphinx
16-
17-
# run format verification
18-
- tox -e black-check
19-
20-
# run unit tests
21-
- AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN=
22-
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= AWS_DEFAULT_REGION=
23-
tox -e py36,py27 -- tests/unit
24-
25-
# run notebook test
26-
- |
27-
if has-matching-changes "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
28-
echo "running notebook test"
29-
./tests/scripts/run-notebook-test.sh
30-
else
31-
echo "skipping notebook test"
32-
fi
33-
34-
# wait its turn to run integration tests
35-
- ACCOUNT=$(aws sts get-caller-identity --output text | awk '{print $1}')
36-
- S3_BUCKET_DIR=s3://sagemaker-us-west-2-${ACCOUNT}/ci-lock
37-
3810
- |
39-
while true; do
40-
LAST_LOCK=$(aws s3 ls ${S3_BUCKET_DIR} | sort | tail -n 1 | awk '{print $4}')
41-
42-
if [[ -z "$LAST_LOCK" ]]
43-
then
44-
echo "No locks. Creating lock."
45-
LOCK_FILE=$(date +%s)
46-
touch ${LOCK_FILE}
47-
48-
aws s3 cp ${LOCK_FILE} ${S3_BUCKET_DIR}/${LOCK_FILE}
49-
50-
else
51-
echo "Waiting on lock."
52-
sleep 30
53-
fi
54-
done
55-
56-
# run integration tests
57-
- |
58-
if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
59-
IGNORE_COVERAGE=- tox -e py36,py27 -- tests/integ -n 24 --boxed --reruns 2
60-
else
61-
echo "skipping integration tests"
62-
fi
11+
python ci-scripts/queue_build.py
12+
sleep 20m
13+
14+
# # run linters
15+
# - tox -e flake8,pylint
16+
#
17+
# # run package and docbuild checks
18+
# - tox -e twine
19+
# - tox -e sphinx
20+
#
21+
# # run format verification
22+
# - tox -e black-check
23+
#
24+
# # run unit tests
25+
# - AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN=
26+
# AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= AWS_DEFAULT_REGION=
27+
# tox -e py36,py27 -- tests/unit
28+
#
29+
# # run notebook test
30+
# - |
31+
# if has-matching-changes "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
32+
# echo "running notebook test"
33+
# ./tests/scripts/run-notebook-test.sh
34+
# else
35+
# echo "skipping notebook test"
36+
# fi
37+
#
38+
# # wait its turn to run integration tests
39+
# - ACCOUNT=$(aws sts get-caller-identity --output text | awk '{print $1}')
40+
# - S3_BUCKET_DIR=s3://sagemaker-us-west-2-${ACCOUNT}/ci-lock
41+
#
42+
# # run integration tests
43+
# - |
44+
# if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
45+
# python ci/queue_build.py
46+
# IGNORE_COVERAGE=- tox -e py36,py27 -- tests/integ -n 24 --boxed --reruns 2
47+
# else
48+
# echo "skipping integration tests"
49+
# fi
6350
finally:
64-
- aws s3 rm --recursive ${S3_BUCKET_DIR}
51+
- FILENAME=$(ls ci-lock/)
52+
- ACCOUNT=$(aws sts get-caller-identity --output text | awk '{print $1}')
53+
- S3_BUCKET_DIR=s3://sagemaker-us-west-2-${ACCOUNT}/ci-lock/
54+
- aws s3 rm ${S3_BUCKET_DIR}${FILENAME}

ci-scripts/queue_build.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
import os
14+
import time
15+
import boto3
16+
17+
account = boto3.client("sts").get_caller_identity()["Account"]
18+
bucket_name = 'sagemaker-us-west-2-%s' % account
19+
20+
21+
def queue_build():
22+
build_id = os.environ.get('CODEBUILD_BUILD_ID', 'CODEBUILD-BUILD-ID')
23+
source_version = os.environ.get('CODEBUILD_SOURCE_VERSION', 'CODEBUILD-SOURCE-VERSION')
24+
ticket_number = int(time.time())
25+
filename = '%s_%s_%s' % (ticket_number, build_id, source_version)
26+
27+
print('Created queue ticket %s' % ticket_number)
28+
29+
_write_ticket(filename)
30+
files = _list_tickets()
31+
_cleanup_tickets_older_than_8_days(files)
32+
_wait_for_other_builds(files, ticket_number)
33+
34+
35+
def _build_info_from_file(file):
36+
filename = file.key.split('/')[1]
37+
ticket_number, build_id, source_version = filename.split('_')
38+
return int(ticket_number), build_id, source_version
39+
40+
41+
def _wait_for_other_builds(files, ticket_number):
42+
newfiles = list(filter(lambda file: not _file_older_than(file), files))
43+
sorted_files = list(sorted(newfiles, key=lambda y: y.key))
44+
45+
print('build queue status:')
46+
print()
47+
48+
for order, file in enumerate(sorted_files):
49+
file_ticket_number, build_id, source_version = _build_info_from_file(file)
50+
print('%s -> %s %s, ticket number: %s' % (order, build_id, source_version, file_ticket_number))
51+
52+
for file in sorted_files:
53+
file_ticket_number, build_id, source_version = _build_info_from_file(file)
54+
55+
if file_ticket_number == ticket_number:
56+
57+
break
58+
else:
59+
print('waiting on build %s %s %s' % (build_id, source_version, file_ticket_number))
60+
file.wait_until_not_exists()
61+
62+
63+
def _cleanup_tickets_older_than_8_days(files):
64+
oldfiles = list(filter(_file_older_than, files))
65+
for file in oldfiles:
66+
print('object %s older than 8 hours. Deleting' % file.key)
67+
file.delete()
68+
return files
69+
70+
71+
def _list_tickets():
72+
s3 = boto3.resource('s3')
73+
bucket = s3.Bucket(bucket_name)
74+
objects = [file for file in bucket.objects.filter(Prefix='ci-lock/')]
75+
files = list(filter(lambda x: x != 'ci-lock/', objects))
76+
return files
77+
78+
79+
def _file_older_than(file):
80+
timelimit = 60 * 60 * 8
81+
82+
file_ticket_number, build_id, source_version = _build_info_from_file(file)
83+
84+
return int(time.time()) - file_ticket_number > timelimit
85+
86+
87+
def _write_ticket(ticket_number):
88+
89+
if not os.path.exists('ci-lock'):
90+
os.mkdir('ci-lock')
91+
92+
filename = 'ci-lock/' + ticket_number
93+
with open(filename, 'w') as file:
94+
file.write(ticket_number)
95+
boto3.Session().resource("s3").Object(bucket_name, filename).upload_file(filename)
96+
97+
98+
if __name__ == '__main__':
99+
queue_build()

0 commit comments

Comments
 (0)