Skip to content

Commit

Permalink
Update reqs and fix issues (#1030)
Browse files Browse the repository at this point in the history
* Update reqs and fix issues

* Drop python 3.7 and earlier support

* More formatting fixes
  • Loading branch information
kddejong authored Oct 6, 2023
1 parent a3ec96f commit 5848cc8
Show file tree
Hide file tree
Showing 50 changed files with 346 additions and 306 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
AWS_DEFAULT_REGION: us-east-1
strategy:
matrix:
python: [ 3.7, 3.8, 3.9, "3.10" ]
python: [ 3.8, 3.9, "3.10" ]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand Down
1 change: 0 additions & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ persistent=yes
disable=
missing-docstring, # not everything needs a docstring
fixme, # work in progress
bad-continuation, # clashes with black
duplicate-code, # finds dupes between tests and plugins
too-few-public-methods, # triggers when inheriting
ungrouped-imports, # clashes with isort
Expand Down
22 changes: 11 additions & 11 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# better interactive session, debugger
ipython>=7.7.0
ipdb>=0.12
ipython>=8.0.0
ipdb>=0.13

# testing tools
pylint==2.8.3
coverage>=4.5.4
pytest>=6.0.0
pytest-cov>=2.7.1
pytest-random-order>=1.0.4
hypothesis>=4.32.3
pytest-localserver>=0.5.0
pylint==3.0.1
coverage>=7.3.2
pytest>=7.4.2
pytest-cov>=4.1.0
pytest-random-order>=1.1.0
hypothesis>=6.87.1
pytest-localserver>=0.8.0

# commit hooks
pre-commit>=1.18.1
pre-commit>=3.4.0

# packaging
twine>=3.1.0
twine>=4.0.2
2 changes: 0 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ def find_version(*file_paths):
"Topic :: Software Development :: Code Generators",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
6 changes: 2 additions & 4 deletions src/rpdk/core/boto_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ def get_temporary_credentials(session, key_names=BOTO_CRED_KEYS, role_arn=None):
region_name=session.region_name,
)
if role_arn:
session_name = "CloudFormationContractTest-{:%Y%m%d%H%M%S}".format(
datetime.now()
)
session_name = f"CloudFormationContractTest-{datetime.now():%Y%m%d%H%M%S}"
try:
response = sts_client.assume_role(
RoleArn=role_arn, RoleSessionName=session_name, DurationSeconds=900
Expand All @@ -54,7 +52,7 @@ def get_temporary_credentials(session, key_names=BOTO_CRED_KEYS, role_arn=None):
role_arn,
)
raise DownstreamError() from Exception(
"Could not assume specified role '{}'".format(role_arn)
"Could not assume specified role '{role_arn}'"
)
temp = response["Credentials"]
creds = (temp["AccessKeyId"], temp["SecretAccessKey"], temp["SessionToken"])
Expand Down
8 changes: 5 additions & 3 deletions src/rpdk/core/build_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ def setup_subparser(subparsers, parents):
parser.add_argument("--image-name", help="Image name")
parser.add_argument(
"--executable",
help="The relative path to the handler executable"
" that will be built into the docker image"
" (ie target/myjar.jar)",
help=(
"The relative path to the handler executable"
" that will be built into the docker image"
" (ie target/myjar.jar)"
),
)
8 changes: 4 additions & 4 deletions src/rpdk/core/contract/hook_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,9 @@ def is_update_invocation_point(invocation_point):

def assert_time(self, start_time, end_time, action):
timeout_in_seconds = self._timeout_in_seconds
assert end_time - start_time <= timeout_in_seconds, (
"Handler %r timed out." % action
)
assert (
end_time - start_time <= timeout_in_seconds
), f"Handler {action!r} timed out."

def _make_payload(
self,
Expand Down Expand Up @@ -472,7 +472,7 @@ def call_and_assert(
**kwargs,
):
if assert_status not in [HookStatus.SUCCESS, HookStatus.FAILED]:
raise ValueError("Assert status {} not supported.".format(assert_status))
raise ValueError(f"Assert status {assert_status} not supported.")

status, response = self.call(invocation_point, target, target_model, **kwargs)
if assert_status == HookStatus.SUCCESS:
Expand Down
63 changes: 28 additions & 35 deletions src/rpdk/core/contract/resource_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ def path_exists(document, path):
_prop, _resolved_path, _parent = traverse(document, path)
except LookupError:
return False
else:
return True

return True


def prune_properties_from_model(model, paths):
Expand Down Expand Up @@ -282,18 +282,16 @@ def has_only_writable_identifiers(self):
)

def assert_write_only_property_does_not_exist(self, resource_model):

error_list = []
if self.write_only_paths:
for write_only_property in self.write_only_paths:
val = self.key_error_safe_traverse(resource_model, write_only_property)
if val:
error_list.append(write_only_property[1])
assertion_error_message = (
"The model MUST NOT return properties defined as "
"writeOnlyProperties in the resource schema "
"\n Write only properties in resource model : %s \n Output Resource Model : %s \n"
% (error_list, resource_model)
"The model MUST NOT return properties defined as writeOnlyProperties"
" in the resource schema \n Write only properties in resource model :"
f" {error_list} \n Output Resource Model : {resource_model} \n"
)
assert not any(error_list), assertion_error_message

Expand All @@ -302,13 +300,13 @@ def get_metadata(self):
properties = self._schema["properties"]
except KeyError:
return set()
else:
return {
prop
for prop in properties.keys()
if "insertionOrder" in properties[prop]
and properties[prop]["insertionOrder"] == "false"
}

return {
prop
for prop in properties.keys()
if "insertionOrder" in properties[prop]
and properties[prop]["insertionOrder"] == "false"
}

@property
def strategy(self):
Expand Down Expand Up @@ -456,11 +454,10 @@ def compare(self, inputs, outputs):

def compare_model(self, inputs, outputs, path=()):
assertion_error_message = (
"All properties specified in the request MUST "
"be present in the model returned, and they MUST"
" match exactly, with the exception of properties"
" defined as writeOnlyProperties in the resource schema \n Request Model : %s \n Returned Model : %s \n"
% (inputs, outputs)
"All properties specified in the request MUST be present in the model"
" returned, and they MUST match exactly, with the exception of properties"
" defined as writeOnlyProperties in the resource schema \n Request Model :"
f" {inputs} \n Returned Model : {outputs} \n"
)
try:
if isinstance(inputs, dict):
Expand Down Expand Up @@ -488,13 +485,9 @@ def compare_model(self, inputs, outputs, path=()):
else:
if inputs[key] != outputs[key]:
assertion_error_message = (
"%s Value for property %s in Request Model(%s) and Response Model(%s) does not match"
% (
assertion_error_message,
key,
inputs[key],
outputs[key],
)
f"{assertion_error_message} Value for property {key} in"
f" Request Model({inputs[key]}) and Response"
f" Model({outputs[key]}) does not match"
)
assert inputs[key] == outputs[key], assertion_error_message
else:
Expand Down Expand Up @@ -612,9 +605,9 @@ def assert_time(self, start_time, end_time, action):
if action in (Action.READ, Action.LIST)
else self._timeout_in_seconds * 2
)
assert end_time - start_time <= timeout_in_seconds, (
"Handler %r timed out." % action
)
assert (
end_time - start_time <= timeout_in_seconds
), f"Handler {action!r} timed out."

@staticmethod
def assert_primary_identifier(primary_identifier_paths, resource_model):
Expand Down Expand Up @@ -646,8 +639,8 @@ def is_primary_identifier_equal(
)
except KeyError as e:
raise AssertionError(
"The primaryIdentifier returned in every progress event must\
match the primaryIdentifier passed into the request"
"The primaryIdentifier returned in every progress event must "
"match the primaryIdentifier passed into the request"
) from e

@staticmethod
Expand All @@ -662,8 +655,8 @@ def get_primary_identifier(primary_identifier_path, model):
return pid_list
except KeyError as e:
raise AssertionError(
"The primaryIdentifier returned in every progress event must\
match the primaryIdentifier passed into the request \n"
"The primaryIdentifier returned in every progress event must "
"match the primaryIdentifier passed into the request \n"
) from e

def _make_payload(
Expand Down Expand Up @@ -761,7 +754,7 @@ def call_and_assert(
if not self.has_required_handlers():
raise ValueError("Create/Read/Delete handlers are required")
if assert_status not in [OperationStatus.SUCCESS, OperationStatus.FAILED]:
raise ValueError("Assert status {} not supported.".format(assert_status))
raise ValueError(f"Assert status {assert_status} not supported.")

status, response = self.call(action, current_model, previous_model, **kwargs)
if assert_status == OperationStatus.SUCCESS:
Expand Down Expand Up @@ -857,7 +850,7 @@ def validate_model_contain_tags(self, inputs):
if key == tag_property_name:
return True
else:
raise assertion_error_message
raise AssertionError(assertion_error_message)
except Exception as exception:
raise AssertionError(assertion_error_message) from exception
return False
Expand Down
15 changes: 8 additions & 7 deletions src/rpdk/core/contract/suite/hook/hook_handler_commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
def test_hook_success(hook_client, invocation_point, target, target_model):
if HookClient.is_update_invocation_point(invocation_point):
raise ValueError(
"Invocation point {} not supported for this testing operation".format(
invocation_point
)
f"Invocation point {invocation_point} not supported for this testing"
" operation"
)

_status, response, _error_code = hook_client.call_and_assert(
Expand All @@ -39,9 +38,8 @@ def test_hook_success(hook_client, invocation_point, target, target_model):
def test_update_hook_success(hook_client, invocation_point, target, target_model):
if not HookClient.is_update_invocation_point(invocation_point):
raise ValueError(
"Invocation point {} not supported for testing UPDATE hook operation".format(
invocation_point
)
f"Invocation point {invocation_point} not supported for testing UPDATE hook"
" operation"
)

_status, response, _error_code = hook_client.call_and_assert(
Expand Down Expand Up @@ -85,7 +83,10 @@ def test_hook_handlers_failed(hook_client, invocation_point):

@failed_event(
error_code=HandlerErrorCode.UnsupportedTarget,
msg="A hook handler MUST return FAILED with a UnsupportedTarget error code if the target is not supported",
msg=(
"A hook handler MUST return FAILED with a UnsupportedTarget error code if the"
" target is not supported"
),
)
def test_hook_unsupported_target(hook_client, invocation_point):
if not hook_client.handler_has_wildcard_targets(invocation_point):
Expand Down
14 changes: 9 additions & 5 deletions src/rpdk/core/contract/suite/resource/contract_asserts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ def response_contains_resource_model_equal_updated_model(
assert response["resourceModel"] == {
**current_resource_model,
**update_resource_model,
}, "All properties specified in the update request MUST be present in the \
model returned, and they MUST match exactly, with the exception of \
properties defined as writeOnlyProperties in the resource schema"
}, (
"All properties specified in the update request MUST be present in the "
"model returned, and they MUST match exactly, with the exception of "
"properties defined as writeOnlyProperties in the resource schema"
)


@decorate()
Expand All @@ -35,8 +37,10 @@ def response_contains_unchanged_primary_identifier(
resource_client.primary_identifier_paths,
current_resource_model,
response["resourceModel"],
), "PrimaryIdentifier returned in every progress event must match \
the primaryIdentifier passed into the request"
), (
"PrimaryIdentifier returned in every progress event must match the"
" primaryIdentifier passed into the request"
)


@decorate(after=False)
Expand Down
42 changes: 22 additions & 20 deletions src/rpdk/core/contract/suite/resource/handler_commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ def test_create_success(resource_client, current_resource_model):

@failed_event(
error_code=HandlerErrorCode.AlreadyExists,
msg="A create handler MUST NOT create multiple resources given\
the same idempotency token",
msg=(
"A create handler MUST NOT create multiple resources given the same "
"idempotency token"
),
)
def test_create_failure_if_repeat_writeable_id(resource_client, current_resource_model):
LOG.debug(
"at least one identifier is writeable; "
"performing duplicate-CREATE-failed test"
"at least one identifier is writeable; performing duplicate-CREATE-failed test"
)
# Should fail, because different clientRequestToken for the same
# resource model means that the same resource is trying to be
Expand All @@ -59,8 +60,10 @@ def test_read_success(resource_client, current_resource_model):

@failed_event(
error_code=HandlerErrorCode.NotFound,
msg="A read handler MUST return FAILED with a NotFound error code\
if the resource does not exist",
msg=(
"A read handler MUST return FAILED with a NotFound error code if the "
"resource does not exist"
),
)
def test_read_failure_not_found(
resource_client,
Expand Down Expand Up @@ -114,16 +117,11 @@ def error_test_model_in_list(resource_client, current_resource_model, message):
)
if resource_model_primary_identifier != current_model_primary_identifier:
assertion_error_message = (
"%s \n Resource Model primary identifier %s does not match with "
"Current Resource Model primary identifier %s \n Resource Model : %s"
" \n Currrent Model : %s "
% (
message,
resource_model_primary_identifier[0],
current_model_primary_identifier[0],
resource_model,
current_resource_model,
)
f"{message} \n Resource Model primary identifier"
f" {resource_model_primary_identifier[0]} does not match with Current"
" Resource Model primary identifier"
f" {current_model_primary_identifier[0]} \n Resource Model :"
f" {resource_model} \n Currrent Model : {current_resource_model} "
)
return assertion_error_message
return assertion_error_message
Expand All @@ -145,8 +143,10 @@ def test_update_success(resource_client, update_resource_model, current_resource

@failed_event(
error_code=HandlerErrorCode.NotFound,
msg="An update handler MUST return FAILED with a NotFound error code\
if the resource did not exist prior to the update request",
msg=(
"An update handler MUST return FAILED with a NotFound error code if the "
"resource did not exist prior to the update request"
),
)
def test_update_failure_not_found(resource_client, current_resource_model):
update_model = resource_client.generate_update_example(current_resource_model)
Expand All @@ -165,8 +165,10 @@ def test_delete_success(resource_client, current_resource_model):

@failed_event(
error_code=HandlerErrorCode.NotFound,
msg="A delete hander MUST return FAILED with a NotFound error code\
if the resource did not exist prior to the delete request",
msg=(
"A delete hander MUST return FAILED with a NotFound error code if the "
"resource did not exist prior to the delete request"
),
)
def test_delete_failure_not_found(resource_client, current_resource_model):
_status, _response, error_code = resource_client.call_and_assert(
Expand Down
Loading

0 comments on commit 5848cc8

Please sign in to comment.