Skip to content

Commit c6f4065

Browse files
committed
chore: performance tests for ESDK-python
1 parent 70d1364 commit c6f4065

36 files changed

+953
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ __pycache__
3333
.pytest_cache
3434
# Ignore key materials generated by examples or tests
3535
test_keyrings/
36+
# Ignore results of performance test
37+
performance_tests/results/*
3638

3739
# PyCharm
3840
.idea/

performance_tests/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Performance Tests for ESDK Python

performance_tests/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Stub module indicator to make linter configuration simpler."""
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Script for consolidating results for execution times"""
4+
5+
import csv
6+
import sys
7+
8+
9+
def calculate_statistics(_csv_file):
10+
"""Calculate min, max and average statistics for execution times in a CSV file."""
11+
with open(_csv_file, 'r', encoding='utf-8') as file:
12+
reader = csv.reader(file)
13+
data = [float(row[0]) for row in reader]
14+
15+
# Calculate statistics
16+
if data:
17+
_total_entries = len(data)
18+
_average = sum(data) / _total_entries
19+
_minimum = min(data)
20+
_maximum = max(data)
21+
return _total_entries, _average, _minimum, _maximum
22+
23+
return None
24+
25+
26+
if __name__ == "__main__":
27+
if len(sys.argv) != 2:
28+
print("Usage: python consolidate_results.py <csv_file>")
29+
sys.exit(1)
30+
31+
csv_file = sys.argv[1]
32+
statistics = calculate_statistics(csv_file)
33+
if statistics:
34+
total_entries, average, minimum, maximum = statistics
35+
print("CSV File:", csv_file)
36+
print("Total Entries:", total_entries)
37+
print("Average:", average)
38+
print("Minimum:", minimum)
39+
print("Maximum:", maximum)
40+
else:
41+
print("No data found in the CSV file.")

performance_tests/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
attrs >= 17.4.0
2+
aws-encryption-sdk>=2.3.0
3+
pytest>=3.3.1
4+
tqdm
5+
click
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
amazon-cryptographic-material-providers-test-vectors @ git+https://github.com/aws/aws-cryptographic-material-providers-library.git@lucmcdon/python-mpl#subdirectory=TestVectorsAwsCryptographicMaterialProviders/runtimes/python

performance_tests/setup.cfg

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[wheel]
2+
universal = 1
3+
4+
[metadata]
5+
license_file = LICENSE
6+
7+
[coverage:run]
8+
branch = True
9+
10+
[coverage:report]
11+
show_missing = True
12+
13+
[mypy]
14+
ignore_missing_imports = True
15+
16+
[flake8]
17+
max_complexity = 10
18+
max_line_length = 120
19+
import_order_style = google
20+
application_import_names = aws_encryption_sdk_cli
21+
builtins = raw_input
22+
ignore =
23+
# Ignoring D205 and D400 because of false positives
24+
D205, D400,
25+
# E203 is not PEP8 compliant https://github.com/ambv/black#slices
26+
E203,
27+
# W503 is not PEP8 compliant https://github.com/ambv/black#line-breaks--binary-operators
28+
W503
29+
30+
[doc8]
31+
max-line-length = 120
32+
33+
[isort]
34+
line_length = 120
35+
# https://github.com/timothycrosley/isort#multi-line-output-modes
36+
multi_line_output = 3
37+
include_trailing_comma = True
38+
force_grid_wrap = 0
39+
combine_as_imports = True
40+
not_skip = __init__.py
41+
known_third_party = attr,aws_encryption_sdk,pytest,setuptools,six

performance_tests/setup.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
"""Performance test for the AWS Encryption SDK for Python."""
2+
import os
3+
import re
4+
5+
from setuptools import find_packages, setup
6+
7+
VERSION_RE = re.compile(r"""__version__ = ['"]([0-9.]+)['"]""")
8+
HERE = os.path.abspath(os.path.dirname(__file__))
9+
10+
11+
def read(*args):
12+
"""Read complete file contents."""
13+
return open(os.path.join(HERE, *args), encoding="utf-8").read() # pylint: disable=consider-using-with
14+
15+
16+
def get_version():
17+
"""Read the version from this module."""
18+
init = read("src", "aws_encryption_sdk_performance_tests", "__init__.py")
19+
return VERSION_RE.search(init).group(1)
20+
21+
22+
setup(
23+
name="aws-encryption-sdk-performance-tests",
24+
packages=find_packages("src"),
25+
package_dir={"": "src"},
26+
author="Amazon Web Services",
27+
maintainer="Amazon Web Services",
28+
author_email="[email protected]",
29+
url="https://github.com/awslabs/aws-encryption-sdk-python",
30+
description="Performance tests for the AWS Encryption SDK for Python",
31+
keywords="aws-encryption-sdk aws kms encryption",
32+
license="Apache License 2.0",
33+
version=get_version(),
34+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Stub module indicator to make linter configuration simpler."""
4+
__version__ = "0.0.0"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Stub module indicator to make linter configuration simpler."""
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Performance tests for the AWS KMS keyring."""
4+
5+
import aws_encryption_sdk
6+
import boto3
7+
from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders
8+
from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig
9+
from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsKeyringInput
10+
from aws_cryptographic_materialproviders.mpl.references import IKeyring
11+
from aws_encryption_sdk import CommitmentPolicy
12+
13+
14+
def create_keyring(
15+
kms_key_id: str
16+
):
17+
"""Demonstrate how to create an AWS KMS keyring.
18+
19+
Usage: create_keyring(kms_key_id)
20+
:param kms_key_id: KMS Key identifier for the KMS key you want to use.
21+
:type kms_key_id: string
22+
23+
For more information on KMS Key identifiers, see
24+
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id
25+
"""
26+
# Create a boto3 client for KMS.
27+
kms_client = boto3.client('kms', region_name="us-west-2")
28+
29+
# Create a KMS keyring
30+
mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders(
31+
config=MaterialProvidersConfig()
32+
)
33+
34+
keyring_input: CreateAwsKmsKeyringInput = CreateAwsKmsKeyringInput(
35+
kms_key_id=kms_key_id,
36+
kms_client=kms_client
37+
)
38+
39+
keyring: IKeyring = mat_prov.create_aws_kms_keyring(
40+
input=keyring_input
41+
)
42+
43+
return keyring
44+
45+
46+
def encrypt_using_keyring(
47+
plaintext_data: bytes,
48+
keyring: IKeyring
49+
):
50+
"""Demonstrate how to encrypt plaintext data using an AWS KMS keyring.
51+
52+
Usage: encrypt_using_keyring(plaintext_data, keyring)
53+
:param plaintext_data: plaintext data you want to encrypt
54+
:type: bytes
55+
:param keyring: Keyring to use for encryption.
56+
:type keyring: IKeyring
57+
"""
58+
client = aws_encryption_sdk.EncryptionSDKClient(
59+
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
60+
)
61+
62+
_, _ = client.encrypt(
63+
source=plaintext_data,
64+
keyring=keyring
65+
)
66+
67+
68+
def decrypt_using_keyring(
69+
ciphertext_data: bytes,
70+
keyring: IKeyring
71+
):
72+
"""Demonstrate how to decrypt ciphertext data using an AWS KMS keyring.
73+
74+
Usage: decrypt_using_keyring(ciphertext_data, keyring)
75+
:param ciphertext_data: ciphertext data you want to decrypt
76+
:type: bytes
77+
:param keyring: Keyring to use for decryption.
78+
:type keyring: IKeyring
79+
"""
80+
client = aws_encryption_sdk.EncryptionSDKClient(
81+
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
82+
)
83+
84+
_, _ = client.decrypt(
85+
source=ciphertext_data,
86+
keyring=keyring
87+
)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[MESSAGE CONTROL]
2+
# Disabling messages that either we don't care about we intentionally break.
3+
disable =
4+
import-error, # ignore mpl import errors
5+
invalid-name, # we prefer long, descriptive, names for examples
6+
bad-continuation, # we let black handle this
7+
ungrouped-imports, # we let isort handle this
8+
no-member, # breaks with attrs
9+
no-self-use, # interesting to keep in mind for later refactoring, but not blocking
10+
useless-object-inheritance, # we need to support Python 2, so no, not useless
11+
duplicate-code, # some examples may be similar
12+
too-few-public-methods, # does not allow value stores
13+
too-many-locals, # examples may sometimes have more locals defined for clarity than would be appropriate in code
14+
no-else-return, # we omit this on purpose for brevity where it would add no value
15+
attribute-defined-outside-init, # breaks with attrs_post_init
16+
abstract-method, # throws false positives on io.BaseIO grandchildren
17+
redefined-outer-name, # we do this on purpose in multiple places
18+
consider-using-f-string # disable until 2022-05-05; 6 months after 3.5 deprecation
19+
20+
[BASIC]
21+
# Allow function names up to 50 characters
22+
function-rgx = [a-z_][a-z0-9_]{2,50}$
23+
# Allow method names up to 50 characters
24+
method-rgx = [a-z_][a-z0-9_]{2,50}$
25+
# Allow class attribute names up to 50 characters
26+
# Whitelist class attribute names: iv
27+
class-attribute-rgx = (([A-Za-z_][A-Za-z0-9_]{2,50}|(__.*__))$)|(^iv$)
28+
# Whitelist attribute names: iv
29+
attr-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$)
30+
# Whitelist argument names: iv, b
31+
argument-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$)|(^b$)
32+
# Whitelist variable names: iv, b, _b, x, y, r, s
33+
variable-rgx = ([a-z_][a-z0-9_]{2,30}$)|(^iv$)|(^b$)|(^_b$)|(^x$)|(^y$)|(^r$)|(^s$)
34+
35+
[VARIABLES]
36+
additional-builtins = raw_input
37+
38+
[DESIGN]
39+
max-args = 10
40+
41+
[FORMAT]
42+
max-line-length = 120
43+
44+
[REPORTS]
45+
msg-template = {path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Stub module indicator to make linter configuration simpler."""
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Performance tests for the AWS KMS master key provider."""
4+
5+
import aws_encryption_sdk
6+
from aws_encryption_sdk import CommitmentPolicy
7+
8+
9+
def create_key_provider(
10+
kms_key_id: str
11+
):
12+
"""Demonstrate how to create an AWS KMS master key-provider.
13+
14+
Usage: create_key_provider(kms_key_id)
15+
:param kms_key_id: KMS Key identifier for the KMS key you want to use.
16+
:type kms_key_id: string
17+
18+
For more information on KMS Key identifiers, see
19+
https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id
20+
"""
21+
# Create a KMS master key-provider.
22+
key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=[
23+
kms_key_id,
24+
])
25+
26+
return key_provider
27+
28+
29+
def encrypt_using_key_provider(
30+
plaintext_data: bytes,
31+
key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider
32+
):
33+
"""Demonstrate how to encrypt plaintext data using an AWS KMS master key-provider.
34+
35+
Usage: encrypt_using_key_provider(plaintext_data, key_provider)
36+
:param plaintext_data: plaintext data you want to encrypt
37+
:type: bytes
38+
:param key_provider: Master key provider to use for encryption.
39+
:type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider
40+
"""
41+
client = aws_encryption_sdk.EncryptionSDKClient(
42+
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
43+
)
44+
45+
_, _ = client.encrypt(
46+
source=plaintext_data,
47+
key_provider=key_provider
48+
)
49+
50+
51+
def decrypt_using_key_provider(
52+
ciphertext_data: bytes,
53+
key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider
54+
):
55+
"""Demonstrate how to decrypt ciphertext data using an AWS KMS master key-provider.
56+
57+
Usage: decrypt_using_key_provider(ciphertext_data, key_provider)
58+
:param ciphertext_data: ciphertext data you want to decrypt
59+
:type: bytes
60+
:param key_provider: Master key provider to use for decryption.
61+
:type key_provider: aws_encryption_sdk.key_providers.base.MasterKeyProvider
62+
"""
63+
client = aws_encryption_sdk.EncryptionSDKClient(
64+
commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT
65+
)
66+
67+
_, _ = client.decrypt(
68+
source=ciphertext_data,
69+
key_provider=key_provider
70+
)

0 commit comments

Comments
 (0)