-
Notifications
You must be signed in to change notification settings - Fork 10.6k
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
[PSM interop] Introduce isort/pylint to the GKE framework #29476
Conversation
78a8608
to
42297f7
Compare
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 great, without any exaggeration. Thank you so much for the hard work.
I left a few comments/notes, but this is almost good to go.
@@ -54,7 +53,7 @@ def _replace_binding(policy: 'Policy', binding: 'Policy.Binding', | |||
new_bindings = set(policy.bindings) | |||
new_bindings.discard(binding) | |||
new_bindings.add(new_binding) | |||
return dataclasses.replace(policy, bindings=frozenset(new_bindings)) | |||
return dataclasses.replace(policy, bindings=frozenset(new_bindings)) # pylint: disable=too-many-function-args |
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.
Wait, what's wrong with this?
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.
Good catch. This is still a mystery to me. Here is the raw pylint complaint:
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/iam.py:56:11: E1121: Too many positional arguments for function call (too-many-function-args)
Our usage complies with official doc: https://docs.python.org/3/library/dataclasses.html#dataclasses.replace
I suspect it might be a PyLint issue with dataclasses
library.
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.
Yea, I have the same suspicion. Probably the same as pylint-dev/pylint#3492
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_security.py
Outdated
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_services.py
Outdated
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/framework/xds_url_map_test_resources.py
Outdated
Show resolved
Hide resolved
@@ -102,7 +102,7 @@ def __init__(self, xds_json: JsonType): | |||
for endpoint in xds_config['endpointConfig'][ | |||
'dynamicEndpointConfigs']: | |||
self.eds.append(endpoint['endpointConfig']) | |||
except Exception as e: | |||
except Exception as e: # pylint: disable=broad-except |
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.
Here and below:
Do we really need catching Exception
here? Looking at the code, it can be replaced with LookupError
. But I may be wrong.
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.
Added as TODO. Let's do it in another PR, in case the narrowing of the catch scope causing tests to fail.
default_test_servers: List[_XdsTestServer] = [] | ||
alternate_test_servers: List[_XdsTestServer] = [] |
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 don't think it's required to assign the value, you should be able to just specify the type.
default_test_servers: List[_XdsTestServer] = [] | |
alternate_test_servers: List[_XdsTestServer] = [] | |
default_test_servers: List[_XdsTestServer] | |
alternate_test_servers: List[_XdsTestServer] |
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 was afraid that in case of non-failfast run, we might carry a non-List value, then cause later tests to fail (since they assumed this value to be List, but seen None
). To make the typing work, we will need to wrap it with Optional
.
I found giving it an initial value saves a few lines of code (don't need to do null checks).
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.
From what I see, declaring the type doesn't necessary assign it to None:
Python 3.10.4 (main, Mar 25 2022, 04:37:13) [Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import List
# not defined - error
>>> print(default_test_servers)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'default_test_servers' is not defined
# only type declared - same as not defined - error
>>> default_test_servers: List[str]
>>> print(default_test_servers)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'default_test_servers' is not defined
# type and assignment - all fine
>>> default_test_servers: List[str] = []
>>> print(default_test_servers)
[]
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.
Confirming py3.6 behaves the same as above.
However, if mypy complains about something and it's easier to assign the value - it's fine by me.
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.
TIL it will end up with "not defined" instead of giving it a value... This is very different than other languages. I will update all test cases to use the suggested pattern.
tools/run_tests/xds_k8s_test_driver/tests/url_map/fault_injection_test.py
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/tests/url_map/fault_injection_test.py
Outdated
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/tests/url_map/retry_test.py
Outdated
Show resolved
Hide resolved
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.
Thanks for reviewing this PR! Most comments are resolved, except the styling of variable annotations in test case files. Let's discuss that in the thread in failover_test.py
.
@@ -54,7 +53,7 @@ def _replace_binding(policy: 'Policy', binding: 'Policy.Binding', | |||
new_bindings = set(policy.bindings) | |||
new_bindings.discard(binding) | |||
new_bindings.add(new_binding) | |||
return dataclasses.replace(policy, bindings=frozenset(new_bindings)) | |||
return dataclasses.replace(policy, bindings=frozenset(new_bindings)) # pylint: disable=too-many-function-args |
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.
Good catch. This is still a mystery to me. Here is the raw pylint complaint:
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/iam.py:56:11: E1121: Too many positional arguments for function call (too-many-function-args)
Our usage complies with official doc: https://docs.python.org/3/library/dataclasses.html#dataclasses.replace
I suspect it might be a PyLint issue with dataclasses
library.
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_security.py
Outdated
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/framework/infrastructure/gcp/network_services.py
Outdated
Show resolved
Hide resolved
@@ -102,7 +102,7 @@ def __init__(self, xds_json: JsonType): | |||
for endpoint in xds_config['endpointConfig'][ | |||
'dynamicEndpointConfigs']: | |||
self.eds.append(endpoint['endpointConfig']) | |||
except Exception as e: | |||
except Exception as e: # pylint: disable=broad-except |
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.
Added as TODO. Let's do it in another PR, in case the narrowing of the catch scope causing tests to fail.
@@ -362,13 +360,13 @@ def tearDownClass(cls): | |||
|
|||
def _fetch_and_check_xds_config(self): | |||
# Cleanup state for this attempt | |||
self._xds_json_config = None | |||
self._xds_json_config = None # pylint: disable=attribute-defined-outside-init |
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.
Todo added.
I attempted that approach, the problem is unittest.TestCase
contains too much magic. Theoretically, the variable declaration should happen in the constructor, but the constructor is invoked by unittest
's internal code. To keep magic working, we might make the __init__
function overly complex. There might be an elegant way to pass the last-seen config to caller across the retry-layer. Feel free to suggest.
tools/run_tests/xds_k8s_test_driver/framework/xds_url_map_testcase.py
Outdated
Show resolved
Hide resolved
default_test_servers: List[_XdsTestServer] = [] | ||
alternate_test_servers: List[_XdsTestServer] = [] |
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 was afraid that in case of non-failfast run, we might carry a non-List value, then cause later tests to fail (since they assumed this value to be List, but seen None
). To make the typing work, we will need to wrap it with Optional
.
I found giving it an initial value saves a few lines of code (don't need to do null checks).
tools/run_tests/xds_k8s_test_driver/tests/url_map/fault_injection_test.py
Show resolved
Hide resolved
tools/run_tests/xds_k8s_test_driver/tests/url_map/fault_injection_test.py
Outdated
Show resolved
Hide resolved
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.
All good! Thank you for getting this done! This will go a long way - from making reviews simpler, to stability improvements.
Let's re-run tests before merging this. Also, better to postpone the merge so we don't break anything over the weekend. |
Interestingly, Google served Golang binaries are unavailable now causing Kokoro jobs to fail:
|
All xDS interop test passed, except AffinityTest failed due to known flake:
|
* [PSM interop] Introduce isort/pylint to the GKE framework * Update the rpc_types * Update variable type annotation style in tests/*.py
* [PSM interop] Introduce isort/pylint to the GKE framework * Update the rpc_types * Update variable type annotation style in tests/*.py
* [PSM interop] Introduce isort/pylint to the GKE framework * Update the rpc_types * Update variable type annotation style in tests/*.py
This PR introduces the PSM GKE framework to:
This PR also tries to fix the sanity complains if possible, but there were lots of places where the best fix is ambiguous: https://paste.googleplex.com/5988734773231616 (pylint has ~200 complains). In those ambiguous cases, this PR disables pylint, folks, please lift the disable comments during daily coding (boy-scout rule). Here are a few note-worthy ones:
Our pytype sanity tests might need more work. Currently, we are using a 2019 release of pytype, which don't support Python > 3.7. On the other hand, the latest pytype don't support Python < 3.7. It requires more delicate testing to sort out what version of pytype + Python suits our infra.
Also, the latest pytype release found more issues with our existing code, the upgrade won't be easy.