Skip to content

Commit 6e257e5

Browse files
authored
Tolerate a failed AMI polling attempt (#4727)
* Tolerate a failed AMI polling attempt * Start marking Internet-relates tests to keep them out of the offline step
1 parent d384d7d commit 6e257e5

File tree

7 files changed

+40
-19
lines changed

7 files changed

+40
-19
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ test_debug: check_venv check_build_reqs
145145
test_offline: check_venv check_build_reqs
146146
@printf "$(cyan)All docker related tests will be skipped.$(normal)\n"
147147
TOIL_SKIP_DOCKER=True \
148+
TOIL_SKIP_ONLINE=True \
148149
python -m pytest -vv --timeout=600 --strict-markers --log-level DEBUG --log-cli-level INFO $(cov) -n $(threads) --dist loadscope $(tests) -m "$(marker)"
149150

150151
# This target will run about 1 minute of tests, and stop at the first failure

common.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export TOIL_AWS_NODE_DEBUG?=False # Don't shut down EC2 instances that fail so
6969
export TOIL_TEST_INTEGRATIVE?=False # If ``True``, this allows the integration tests to run.
7070
export TOIL_TEST_QUICK?=False # If ``True``, long running tests are skipped.
7171
export TOIL_SKIP_DOCKER?=False # Skip docker dependent tests
72+
export TOIL_SKIP_ONLINE?=False # Skip Internet-dependent tests
7273

7374
export TOIL_AWS_KEYNAME?=id_rsa # SSH key to use for tests in AWS.
7475
export TOIL_GOOGLE_KEYNAME?=id_rsa # SSH key to use for tests in google.

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ markers =
2828
local_cuda
2929
lsf
3030
mesos
31+
online
3132
rsync
3233
server_mode
3334
slow

src/toil/lib/aws/ami.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from urllib.error import HTTPError, URLError
77

88
from botocore.client import BaseClient
9+
from botocore.exceptions import ClientError
910

1011
from toil.lib.retry import retry
1112

@@ -155,11 +156,18 @@ def feed_flatcar_ami_release(ec2_client: BaseClient, architecture: str = 'amd64'
155156

156157
for ami in flatcar_release_feed_amis(region, architecture, source):
157158
# verify it exists on AWS
158-
response = ec2_client.describe_images(Filters=[{'Name': 'image-id', 'Values': [ami]}]) # type: ignore
159-
if len(response['Images']) == 1 and response['Images'][0]['State'] == 'available':
160-
return ami
161-
else:
162-
logger.warning(f'Flatcar release feed suggests image {ami} which does not exist on AWS in {region}')
159+
try:
160+
response = ec2_client.describe_images(Filters=[{'Name': 'image-id', 'Values': [ami]}]) # type: ignore
161+
if len(response['Images']) == 1 and response['Images'][0]['State'] == 'available':
162+
return ami
163+
else:
164+
logger.warning(f'Flatcar release feed suggests image {ami} which does not exist on AWS in {region}')
165+
except ClientError:
166+
# Sometimes we get back nonsense like:
167+
# botocore.exceptions.ClientError: An error occurred (AuthFailure) when calling the DescribeImages operation: AWS was not able to validate the provided access credentials
168+
# Don't hold that against the AMI.
169+
logger.exception(f'Unable to check if AMI {ami} exists on AWS in {region}; assuming it does')
170+
return ami
163171
# We didn't find it
164172
logger.warning(f'Flatcar release feed does not have an image for region {region} that exists on AWS')
165173
return None

src/toil/test/__init__.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,17 @@ def needs_rsync3(test_item: MT) -> MT:
360360
return test_item
361361

362362

363+
def needs_online(test_item: MT) -> MT:
364+
"""Use as a decorator before test classes or methods to run only if we are meant to talk to the Internet."""
365+
test_item = _mark_test('online', test_item)
366+
if os.getenv('TOIL_SKIP_ONLINE', '').lower() == 'true':
367+
return unittest.skip('Skipping online test.')(test_item)
368+
return test_item
369+
363370
def needs_aws_s3(test_item: MT) -> MT:
364371
"""Use as a decorator before test classes or methods to run only if AWS S3 is usable."""
365372
# TODO: we just check for generic access to the AWS account
366-
test_item = _mark_test('aws-s3', test_item)
373+
test_item = _mark_test('aws-s3', needs_online(test_item))
367374
try:
368375
from boto import config
369376
boto_credentials = config.get('Credentials', 'aws_access_key_id')
@@ -416,7 +423,7 @@ def needs_google_storage(test_item: MT) -> MT:
416423
Cloud is installed and we ought to be able to access public Google Storage
417424
URIs.
418425
"""
419-
test_item = _mark_test('google-storage', test_item)
426+
test_item = _mark_test('google-storage', needs_online(test_item))
420427
try:
421428
from google.cloud import storage # noqa
422429
except ImportError:
@@ -428,7 +435,7 @@ def needs_google_project(test_item: MT) -> MT:
428435
"""
429436
Use as a decorator before test classes or methods to run only if we have a Google Cloud project set.
430437
"""
431-
test_item = _mark_test('google-project', test_item)
438+
test_item = _mark_test('google-project', needs_online(test_item))
432439
test_item = needs_env_var('TOIL_GOOGLE_PROJECTID', "a Google project ID")(test_item)
433440
return test_item
434441

@@ -460,7 +467,7 @@ def needs_kubernetes_installed(test_item: MT) -> MT:
460467

461468
def needs_kubernetes(test_item: MT) -> MT:
462469
"""Use as a decorator before test classes or methods to run only if Kubernetes is installed and configured."""
463-
test_item = needs_kubernetes_installed(test_item)
470+
test_item = needs_kubernetes_installed(needs_online(test_item))
464471
try:
465472
import kubernetes
466473
try:
@@ -539,7 +546,7 @@ def needs_docker(test_item: MT) -> MT:
539546
Use as a decorator before test classes or methods to only run them if
540547
docker is installed and docker-based tests are enabled.
541548
"""
542-
test_item = _mark_test('docker', test_item)
549+
test_item = _mark_test('docker', needs_online(test_item))
543550
if os.getenv('TOIL_SKIP_DOCKER', '').lower() == 'true':
544551
return unittest.skip('Skipping docker test.')(test_item)
545552
if which('docker'):
@@ -552,7 +559,7 @@ def needs_singularity(test_item: MT) -> MT:
552559
Use as a decorator before test classes or methods to only run them if
553560
singularity is installed.
554561
"""
555-
test_item = _mark_test('singularity', test_item)
562+
test_item = _mark_test('singularity', needs_online(test_item))
556563
if which('singularity'):
557564
return test_item
558565
else:
@@ -589,7 +596,7 @@ def needs_docker_cuda(test_item: MT) -> MT:
589596
Use as a decorator before test classes or methods to only run them if
590597
a CUDA setup is available through Docker.
591598
"""
592-
test_item = _mark_test('docker_cuda', test_item)
599+
test_item = _mark_test('docker_cuda', needs_online(test_item))
593600
if have_working_nvidia_docker_runtime():
594601
return test_item
595602
else:
@@ -645,7 +652,7 @@ def needs_celery_broker(test_item: MT) -> MT:
645652
"""
646653
Use as a decorator before test classes or methods to run only if RabbitMQ is set up to take Celery jobs.
647654
"""
648-
test_item = _mark_test('celery', test_item)
655+
test_item = _mark_test('celery', needs_online(test_item))
649656
test_item = needs_env_var('TOIL_WES_BROKER_URL', "a URL to a RabbitMQ broker for Celery")(test_item)
650657
return test_item
651658

@@ -654,7 +661,7 @@ def needs_wes_server(test_item: MT) -> MT:
654661
Use as a decorator before test classes or methods to run only if a WES
655662
server is available to run against.
656663
"""
657-
test_item = _mark_test('wes_server', test_item)
664+
test_item = _mark_test('wes_server', needs_online(test_item))
658665

659666
wes_url = os.environ.get('TOIL_WES_ENDPOINT')
660667
if not wes_url:
@@ -712,7 +719,7 @@ def needs_fetchable_appliance(test_item: MT) -> MT:
712719
the Toil appliance Docker image is able to be downloaded from the Internet.
713720
"""
714721

715-
test_item = _mark_test('fetchable_appliance', test_item)
722+
test_item = _mark_test('fetchable_appliance', needs_online(test_item))
716723
if os.getenv('TOIL_SKIP_DOCKER', '').lower() == 'true':
717724
return unittest.skip('Skipping docker test.')(test_item)
718725
try:
@@ -733,9 +740,7 @@ def integrative(test_item: MT) -> MT:
733740
Use this to decorate integration tests so as to skip them during regular builds.
734741
735742
We define integration tests as A) involving other, non-Toil software components
736-
that we develop and/or B) having a higher cost (time or money). Note that brittleness
737-
does not qualify a test for being integrative. Neither does involvement of external
738-
services such as AWS, since that would cover most of Toil's test.
743+
that we develop and/or B) having a higher cost (time or money).
739744
"""
740745
test_item = _mark_test('integrative', test_item)
741746
if os.getenv('TOIL_TEST_INTEGRATIVE', '').lower() == 'true':

src/toil/test/cwl/cwlTest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
needs_local_cuda,
5858
needs_lsf,
5959
needs_mesos,
60+
needs_online,
6061
needs_slurm,
6162
needs_torque,
6263
needs_wes_server,
@@ -766,6 +767,7 @@ def _expected_streaming_output(self, outDir):
766767

767768

768769
@needs_cwl
770+
@needs_online
769771
class CWLv10Test(ToilTest):
770772
"""
771773
Run the CWL 1.0 conformance tests in various environments.
@@ -896,6 +898,7 @@ def test_kubernetes_cwl_conformance_with_caching(self):
896898

897899

898900
@needs_cwl
901+
@needs_online
899902
class CWLv11Test(ToilTest):
900903
"""
901904
Run the CWL 1.1 conformance tests in various environments.
@@ -950,6 +953,7 @@ def test_kubernetes_cwl_conformance_with_caching(self):
950953

951954

952955
@needs_cwl
956+
@needs_online
953957
class CWLv12Test(ToilTest):
954958
"""
955959
Run the CWL 1.2 conformance tests in various environments.

src/toil/test/lib/test_ec2.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@
2121
flatcar_release_feed_amis,
2222
get_flatcar_ami)
2323
from toil.lib.aws.session import establish_boto3_session
24-
from toil.test import ToilTest, needs_aws_ec2
24+
from toil.test import ToilTest, needs_aws_ec2, needs_online
2525

2626
logger = logging.getLogger(__name__)
2727
logging.basicConfig(level=logging.DEBUG)
2828

29+
@needs_online
2930
class FlatcarFeedTest(ToilTest):
3031
"""Test accessing the Flatcar AMI release feed, independent of the AWS API"""
3132

0 commit comments

Comments
 (0)