-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Protocol tests parsed response validation #3414
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
1491dca
to
ee87925
Compare
ee87925
to
2f031e3
Compare
2f031e3
to
98cd28b
Compare
98cd28b
to
605eb6b
Compare
tools/scripts/run_protocol_tests.py
Outdated
else: # Unix-like | ||
self.process.send_signal(signal.SIGINT) | ||
|
||
time.sleep(0.5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need static sleep? what are we waiting for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to wait a bit to let the process and OS to terminate the process.
tools/scripts/run_protocol_tests.py
Outdated
def wait(self): | ||
"""Wait for the subprocess to complete.""" | ||
if self.process: | ||
return self.process.wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
waits without timeouts have heavily traumatized my up to this point, lets add a reasonable timeout to prevent zombie hosts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is actually a left-over from the AI generated slop I used as an initial draft.
I just removed it.
.collect(Collectors.toSet()); | ||
// include the request shapes | ||
Set<String> requestShapes = testSuite.getCases().stream() | ||
.map(entry -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like we only ever add one item to the set ever, simplified this could just be
testSuite.getCases().stream()
.map(entry -> { return String.format("<aws/%s/model/%s.h>",
serviceModel.getMetadata().getProjectName(),
entry.getGiven().getName() + "Request")})
.collect(Collectors.toSet());
to avoid creating a extra set per test case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy-paste mistake, thank you!
#if(!$expectedResult.isEmpty()) | ||
const ${responseShape.name}& result = outcome.GetResult(); | ||
#end | ||
/* expectedResult = R"( ${expectedResult} )" */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
love the debug comment
605eb6b
to
b7768e6
Compare
/** | ||
* Perform legacy patching of the ec2 model present from the very beginning. | ||
*/ | ||
private void legacyPatchEc2Model() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be optimized to use one loop
private void legacyPatchEc2Model() {
if (!"ec2".equals(serviceModel.getMetadata().getProtocol())) {
return;
}
Map<String, Shape> shapes = serviceModel.getShapes();
Map<String, Shape> updatedShapes = new HashMap<>();
for (Map.Entry<String, Shape> entry : shapes.entrySet()) {
String key = entry.getKey();
Shape shape = entry.getValue();
String newKey = key.replaceAll("Result$", "Response");
shape.setName(shape.getName().replaceAll("Result$", "Response"));
shape.setType(shape.getType().replaceAll("Result$", "Response"));
updatedShapes.put(newKey, shape);
}
shapes.clear();
shapes.putAll(updatedShapes);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The complexity is the same, in addition, this was a copy-pasted method from the actual EC2 client generator.
I refactored it a bit and re-using the existing one.
Additionally,
Map<String, Shape> updatedShapes = new HashMap<>();
would re-shuffle shapes in a map as far as I remember, Json parsers use Linked structures.
tools/scripts/run_protocol_tests.py
Outdated
print(f"No protocol tests found in {self.build_dir}") | ||
self.fail = True | ||
for test in tests: | ||
mock_server = MockHttpServerHandle() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be used with 'with' for cleanup
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, I've refactored this piece with enter/exit methods and with
.
tools/scripts/run_protocol_tests.py
Outdated
""" | ||
|
||
def __init__(self, args): | ||
self.debug = args.get("debug", False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, unused.
Thank you for noticing!
tools/scripts/run_protocol_tests.py
Outdated
self.process = subprocess.Popen(python_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
print(f"Started mock server with PID {self.process.pid}") | ||
|
||
def __del__(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may not be deterministically called by the interpreter per https://docs.python.org/3.4/reference/datamodel.html
Better to use https://book.pythontips.com/en/latest/context_managers.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I've refactored the code to explicitly implicitly call new method stop()
with the with
statement.
tools/scripts/run_protocol_tests.py
Outdated
""" | ||
|
||
def __init__(self): | ||
python_cmd = [shutil.which("python3"), PROTO_TEST_MOCK_HANDLER] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No exception handling found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a bit of exception handling here, but can't do much more than that.
Catch-trace-crash/return -1 is the current approach.
tools/scripts/run_protocol_tests.py
Outdated
mock_server = MockHttpServerHandle() | ||
try: | ||
process = subprocess.run([test], timeout=6 * 60, check=True) | ||
process.check_returncode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is redundant as check is True
per python documentation
If check is true, and the process exits with a non-zero exit code, a [CalledProcessError](https://docs.python.org/3/library/subprocess.html#subprocess.CalledProcessError) exception will be raised. Attributes of that exception hold the arguments, the exit code, and stdout and stderr if they were captured.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, I removed the check.
b7768e6
to
fcffa00
Compare
:return: dict with parsed arguments | ||
""" | ||
parser = argparse.ArgumentParser(description="Protocol tests driver for AWS-SDK-CPP") | ||
parser.add_argument("--debug", action="store_true", help="Print additional information") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny suggestion: parser.add_argument("--debug", action="store_true", default = False, help="Print additional information")
and remove logic later
|
||
def __init__(self): | ||
try: | ||
python_cmd = [shutil.which("python3"), PROTO_TEST_MOCK_HANDLER] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sys.executable if you want to make sure its the same python?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to be sure it is the same interpreter
- test driver
- mock server
- test app
All can be seen as an independent apps.
fcffa00
to
acefa26
Compare
Issue #, if available:
Protocol tests
Description of changes:
Generate parsed response structure validation
Check all that applies:
Check which platforms you have built SDK on to verify the correctness of this PR.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.