Skip to content

Commit 4f4588b

Browse files
mvsusppengk19
authored andcommitted
change: build spec improvements. (aws#888)
1 parent f8c0d72 commit 4f4588b

File tree

4 files changed

+43
-41
lines changed

4 files changed

+43
-41
lines changed

buildspec.yml

+24-17
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,46 @@ phases:
88
build:
99
commands:
1010
# run linters
11-
- tox -e flake8,pylint
12-
# run package and docbuild checks
13-
- tox -e twine
11+
- TOX_PARALLEL_NO_SPINNER=1
12+
- PY_COLORS=0
13+
- tox -e flake8,pylint,twine,black-check --parallel all
1414
- tox -e sphinx
1515

16-
# run format verification
17-
- tox -e black-check
18-
1916
# run unit tests
2017
- AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_SESSION_TOKEN=
2118
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI= AWS_DEFAULT_REGION=
22-
tox -e py36,py27 -- tests/unit
19+
tox -e py36,py27 --parallel all -- tests/unit
2320

24-
# run notebook test
21+
# local mode tests
2522
- |
26-
if has-matching-changes "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
27-
echo "running notebook test"
28-
./tests/scripts/run-notebook-test.sh
29-
else
30-
echo "skipping notebook test"
31-
fi
32-
23+
if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
24+
IGNORE_COVERAGE=- tox -e py36 -- tests/integ -m local_mode --durations 50
25+
IGNORE_COVERAGE=- tox -e py27 -- tests/integ -m local_mode --durations 50
26+
else
27+
echo "skipping integration tests"
28+
fi
29+
3330
# run integration tests
3431
- |
3532
if has-matching-changes "tests/" "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
3633
python3 -u ci-scripts/queue_build.py
37-
IGNORE_COVERAGE=- tox -e py36,py27 -- tests/integ -n 24 --reruns 3
34+
IGNORE_COVERAGE=- tox -e py36 -- tests/integ -m "not local_mode" -n 48 --reruns 3 --reruns-delay 5 --durations 50
35+
IGNORE_COVERAGE=- tox -e py27 -- tests/integ -m "not local_mode" -n 48 --reruns 3 --reruns-delay 5 --durations 50
3836
else
3937
echo "skipping integration tests"
4038
fi
39+
40+
# run notebook test
41+
- |
42+
if has-matching-changes "src/*.py" "setup.py" "setup.cfg" "buildspec.yml"; then
43+
echo "running notebook test"
44+
./tests/scripts/run-notebook-test.sh
45+
else
46+
echo "skipping notebook test"
47+
fi
4148
post_build:
4249
finally:
4350
- FILENAME=$(ls ci-lock/)
4451
- ACCOUNT=$(aws sts get-caller-identity --output text | awk '{print $1}')
4552
- S3_BUCKET_DIR=s3://sagemaker-us-west-2-${ACCOUNT}/ci-lock/
46-
- aws s3 rm ${S3_BUCKET_DIR}${FILENAME}
53+
- aws s3 rm ${S3_BUCKET_DIR}${FILENAME}

setup.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def read_version():
6767
install_requires=required_packages,
6868
extras_require={
6969
"test": [
70-
"tox",
70+
"tox==3.13.1",
7171
"flake8",
7272
"pytest==4.4.1",
7373
"pytest-cov",
@@ -79,6 +79,7 @@ def read_version():
7979
"awslogs",
8080
"pandas",
8181
"black==19.3b0 ; python_version >= '3.6'",
82+
"stopit==1.1.2",
8283
]
8384
},
8485
entry_points={"console_scripts": ["sagemaker=sagemaker.cli.main:main"]},

tests/integ/test_local_mode.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
import pytest
2121
import tempfile
2222

23+
import stopit
24+
2325
import tests.integ.lock as lock
2426
from tests.integ import DATA_DIR, PYTHON_VERSION
25-
from tests.integ.timeout import timeout
2627

2728
from sagemaker.local import LocalSession, LocalSagemakerRuntimeClient, LocalSagemakerClient
2829
from sagemaker.mxnet import MXNet
@@ -86,7 +87,7 @@ def _create_model(output_path):
8687
@pytest.mark.local_mode
8788
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
8889
def test_tf_local_mode(sagemaker_local_session):
89-
with timeout(minutes=5):
90+
with stopit.ThreadingTimeout(5 * 60, swallow_exc=False):
9091
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")
9192

9293
estimator = TensorFlow(
@@ -129,7 +130,7 @@ def test_tf_local_mode(sagemaker_local_session):
129130
@pytest.mark.local_mode
130131
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
131132
def test_tf_distributed_local_mode(sagemaker_local_session):
132-
with timeout(minutes=5):
133+
with stopit.ThreadingTimeout(5 * 60, swallow_exc=False):
133134
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")
134135

135136
estimator = TensorFlow(
@@ -171,7 +172,7 @@ def test_tf_distributed_local_mode(sagemaker_local_session):
171172
@pytest.mark.local_mode
172173
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
173174
def test_tf_local_data(sagemaker_local_session):
174-
with timeout(minutes=5):
175+
with stopit.ThreadingTimeout(5 * 60, swallow_exc=False):
175176
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")
176177

177178
estimator = TensorFlow(
@@ -212,7 +213,7 @@ def test_tf_local_data(sagemaker_local_session):
212213
@pytest.mark.local_mode
213214
@pytest.mark.skipif(PYTHON_VERSION != "py2", reason="TensorFlow image supports only python 2.")
214215
def test_tf_local_data_local_script():
215-
with timeout(minutes=5):
216+
with stopit.ThreadingTimeout(5 * 60, swallow_exc=False):
216217
script_path = os.path.join(DATA_DIR, "iris", "iris-dnn-classifier.py")
217218

218219
estimator = TensorFlow(
@@ -391,7 +392,7 @@ def test_local_transform_mxnet(sagemaker_local_session, tmpdir, mxnet_full_versi
391392
path=os.path.join(data_path, "test"), key_prefix="integ-test-data/mxnet_mnist/test"
392393
)
393394

394-
with timeout(minutes=15):
395+
with stopit.ThreadingTimeout(5 * 60, swallow_exc=False):
395396
mx.fit({"train": train_input, "test": test_input})
396397

397398
transform_input_path = os.path.join(data_path, "transform")

tests/integ/timeout.py

+10-17
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,16 @@
1212
# language governing permissions and limitations under the License.
1313
from __future__ import absolute_import
1414

15-
import signal
1615
from contextlib import contextmanager
1716
import logging
1817
from time import sleep
1918

2019
from awslogs.core import AWSLogs
2120
from botocore.exceptions import ClientError
22-
23-
LOGGER = logging.getLogger("timeout")
21+
import stopit
2422

2523

26-
class TimeoutError(Exception):
27-
pass
24+
LOGGER = logging.getLogger("timeout")
2825

2926

3027
@contextmanager
@@ -43,23 +40,17 @@ def timeout(seconds=0, minutes=0, hours=0):
4340

4441
limit = seconds + 60 * minutes + 3600 * hours
4542

46-
def handler(signum, frame):
47-
raise TimeoutError("timed out after {} seconds".format(limit))
48-
49-
try:
50-
signal.signal(signal.SIGALRM, handler)
51-
signal.alarm(limit)
52-
53-
yield
54-
finally:
55-
signal.alarm(0)
43+
with stopit.ThreadingTimeout(limit, swallow_exc=False) as t:
44+
yield [t]
5645

5746

5847
@contextmanager
5948
def timeout_and_delete_endpoint_by_name(
6049
endpoint_name, sagemaker_session, seconds=0, minutes=45, hours=0
6150
):
62-
with timeout(seconds=seconds, minutes=minutes, hours=hours) as t:
51+
limit = seconds + 60 * minutes + 3600 * hours
52+
53+
with stopit.ThreadingTimeout(limit, swallow_exc=False) as t:
6354
no_errors = False
6455
try:
6556
yield [t]
@@ -89,7 +80,9 @@ def timeout_and_delete_endpoint_by_name(
8980
def timeout_and_delete_model_with_transformer(
9081
transformer, sagemaker_session, seconds=0, minutes=0, hours=0
9182
):
92-
with timeout(seconds=seconds, minutes=minutes, hours=hours) as t:
83+
limit = seconds + 60 * minutes + 3600 * hours
84+
85+
with stopit.ThreadingTimeout(limit, swallow_exc=False) as t:
9386
no_errors = False
9487
try:
9588
yield [t]

0 commit comments

Comments
 (0)