From 607fbf134943583ebc6c9f8a9b86070dd86c409e Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 23 Mar 2018 15:00:40 -0700 Subject: [PATCH 1/3] move common test requirements to test/requirements.txt to simplify running tests outside of tox --- test/requirements.txt | 4 ++++ tox.ini | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 test/requirements.txt diff --git a/test/requirements.txt b/test/requirements.txt new file mode 100644 index 000000000..d1b878ce2 --- /dev/null +++ b/test/requirements.txt @@ -0,0 +1,4 @@ +mock +pytest>=3.3.1 +pytest-cov +pytest-mock \ No newline at end of file diff --git a/tox.ini b/tox.ini index fb28328a1..23c715dc7 100644 --- a/tox.ini +++ b/tox.ini @@ -27,11 +27,7 @@ passenv = # Pass through AWS profile name (useful for local testing) AWS_PROFILE sitepackages = False -deps = - mock - pytest>=3.3.1 - pytest-cov - pytest-mock +deps = -rtest/requirements.txt commands = local: pytest --cov aws_encryption_sdk -m local -l {posargs} integ: pytest --cov aws_encryption_sdk -m integ -l {posargs} From 730b25d8ffc52766899e9302d372317a01cc8d9b Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Fri, 23 Mar 2018 15:28:06 -0700 Subject: [PATCH 2/3] tests that do not need to talk to KMS should not need the CMK environment variable to be set: some of the integ tests were looking for this in setup instead of execution, triggering failures even if the pytest markers for those tests were not requested --- test/integration/integration_test_utils.py | 11 ++++++++++- test/integration/test_i_thread_safety.py | 8 ++++++-- test/integration/test_i_xcompat_kms.py | 10 ++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/test/integration/integration_test_utils.py b/test/integration/integration_test_utils.py index 60ac9de8b..91fa38538 100644 --- a/test/integration/integration_test_utils.py +++ b/test/integration/integration_test_utils.py @@ -16,6 +16,7 @@ from aws_encryption_sdk.key_providers.kms import KMSMasterKeyProvider AWS_KMS_KEY_ID = 'AWS_ENCRYPTION_SDK_PYTHON_INTEGRATION_TEST_AWS_KMS_KEY_ID' +_KMS_MKP = None def get_cmk_arn(): @@ -32,9 +33,17 @@ def get_cmk_arn(): raise ValueError('KMS CMK ARN provided for integration tests much be a key not an alias') -def setup_kms_master_key_provider(): +def setup_kms_master_key_provider(cache=True): """Reads the test_values config file and builds the requested KMS Master Key Provider.""" + global _KMS_MKP # pylint: disable=global-statement + if cache and _KMS_MKP is not None: + return _KMS_MKP + cmk_arn = get_cmk_arn() kms_master_key_provider = KMSMasterKeyProvider() kms_master_key_provider.add_master_key(cmk_arn) + + if cache: + _KMS_MKP = kms_master_key_provider + return kms_master_key_provider diff --git a/test/integration/test_i_thread_safety.py b/test/integration/test_i_thread_safety.py index 0c68d9d63..38ac903bc 100644 --- a/test/integration/test_i_thread_safety.py +++ b/test/integration/test_i_thread_safety.py @@ -22,7 +22,7 @@ from six.moves import queue # six.moves confuses pylint: disable=import-error import aws_encryption_sdk -from .integration_test_utils import setup_kms_master_key_provider +from .integration_test_utils import get_cmk_arn, setup_kms_master_key_provider pytestmark = [pytest.mark.integ] @@ -49,7 +49,7 @@ def crypto_thread_worker(crypto_function, start_pause, input_value, output_queue :param cache: Cache to use with master key provider (optional) """ time.sleep(start_pause) - kms_master_key_provider = setup_kms_master_key_provider() + kms_master_key_provider = setup_kms_master_key_provider(cache=False) if cache is None: # For simplicity, always use a caching CMM; just use a null cache if no cache is specified. cache = aws_encryption_sdk.NullCryptoMaterialsCache() @@ -105,6 +105,8 @@ def random_pause_time(max_seconds=3): def test_threading_loop(): """Test thread safety of client.""" + # Check for the CMK ARN first to fail fast if it is not available + get_cmk_arn() rounds = 20 plaintext_inputs = [ dict(input_value=copy.copy(PLAINTEXT), start_pause=random_pause_time()) @@ -130,6 +132,8 @@ def test_threading_loop(): def test_threading_loop_with_common_cache(): """Test thread safety of client while using common cryptographic materials cache across all threads.""" + # Check for the CMK ARN first to fail fast if it is not available + get_cmk_arn() rounds = 20 cache = aws_encryption_sdk.LocalCryptoMaterialsCache(capacity=40) plaintext_inputs = [ diff --git a/test/integration/test_i_xcompat_kms.py b/test/integration/test_i_xcompat_kms.py index c906bbdd0..8339246ad 100644 --- a/test/integration/test_i_xcompat_kms.py +++ b/test/integration/test_i_xcompat_kms.py @@ -34,7 +34,6 @@ def _file_root(): def _generate_test_cases(): - kms_key_provider = setup_kms_master_key_provider() try: root_dir = os.path.abspath(file_root()) except Exception: # pylint: disable=broad-except @@ -65,15 +64,14 @@ def _generate_test_cases(): if key['provider_id'] == 'aws-kms' and key['decryptable']: _test_cases.append(( os.path.join(base_dir, test_case['plaintext']['filename']), - os.path.join(base_dir, test_case['ciphertext']['filename']), - kms_key_provider + os.path.join(base_dir, test_case['ciphertext']['filename']) )) break return _test_cases -@pytest.mark.parametrize('plaintext_filename,ciphertext_filename,key_provider', _generate_test_cases()) -def test_decrypt_from_file(plaintext_filename, ciphertext_filename, key_provider): +@pytest.mark.parametrize('plaintext_filename, ciphertext_filename', _generate_test_cases()) +def test_decrypt_from_file(plaintext_filename, ciphertext_filename): """Tests decrypt from known good files.""" with open(ciphertext_filename, 'rb') as infile: ciphertext = infile.read() @@ -81,6 +79,6 @@ def test_decrypt_from_file(plaintext_filename, ciphertext_filename, key_provider plaintext = infile.read() decrypted_ciphertext, _header = aws_encryption_sdk.decrypt( source=ciphertext, - key_provider=key_provider + key_provider=setup_kms_master_key_provider() ) assert decrypted_ciphertext == plaintext From de517dd1726f5a279b62224f5cf86df8b869797d Mon Sep 17 00:00:00 2001 From: mattsb42-aws Date: Mon, 26 Mar 2018 19:15:08 -0700 Subject: [PATCH 3/3] * consolidate tox testenv command boilerplate * add testenv that does not pass through or set any environment variables to ensure that local tests work without them --- .travis.yml | 2 ++ tox.ini | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9aa2e548c..627b8cf35 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,8 @@ matrix: env: TOXENV=py36-accept - python: 3.6 env: TOXENV=py36-examples + - python: 3.6 + env: TOXENV=nocmk # disabling Bandit run in Travis pending resolution of https://bugs.launchpad.net/bandit/+bug/1749603 # - python: 3.6 # env: TOXENV=bandit diff --git a/tox.ini b/tox.ini index 23c715dc7..7595b1ea0 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{27,34,35,36}-{local,integ,accept,examples}, + py{27,34,35,36}-{local,integ,accept,examples}, nocmk, bandit, doc8, readme, docs, {flake8,pylint}{,-tests,-examples}, vulture @@ -18,6 +18,9 @@ envlist = # test-release :: Builds dist files and uploads to testpypi pypirc profile. # release :: Builds dist files and uploads to pypi pypirc profile. +[testenv:base-command] +commands = pytest --basetemp={envtmpdir} -l --cov aws_encryption_sdk {posargs} + [testenv] passenv = # Identifies AWS KMS key id to use in integration tests @@ -29,11 +32,18 @@ passenv = sitepackages = False deps = -rtest/requirements.txt commands = - local: pytest --cov aws_encryption_sdk -m local -l {posargs} - integ: pytest --cov aws_encryption_sdk -m integ -l {posargs} - accept: pytest --cov aws_encryption_sdk -m accept -l {posargs} - all: pytest --cov aws_encryption_sdk -l {posargs} - examples: pytest --cov examples/test/ -m examples -l {posargs} + local: {[testenv:base-command]commands} -m local + integ: {[testenv:base-command]commands} -m integ + accept: {[testenv:base-command]commands} -m accept + all: {[testenv:base-command]commands} + examples: {[testenv:base-command]commands} -m examples + +# Verify that local tests work without environment variables present +[testenv:nocmk] +basepython = python3 +sitepackages = False +deps = -rtest/requirements.txt +commands = {[testenv:base-command]commands} -m local # Linters [testenv:flake8]