Conversation
Codecov Report
@@ Coverage Diff @@
## master #297 +/- ##
==========================================
+ Coverage 59.82% 72.43% +12.6%
==========================================
Files 10 10
Lines 341 370 +29
Branches 62 66 +4
==========================================
+ Hits 204 268 +64
+ Misses 121 92 -29
+ Partials 16 10 -6
Continue to review full report at Codecov.
|
| result = json.loads(response_body) | ||
| except ValueError as json_decode_error: | ||
| raise ParseResponseError(response_body, json_decode_error) | ||
| if self.server: |
There was a problem hiding this comment.
just noticed that this check didn't make it over. was it superfluous in the first place? can self.server ever not be set?
There was a problem hiding this comment.
@aoberoi I don't think there's a way it wouldn't be set...
It's set when the client is initialized:
https://github.com/slackapi/python-slackclient/blob/master/slackclient/client.py#L30-L33
tests/test_server.py
Outdated
|
|
||
| def test_server(server): | ||
| def test_server(): | ||
| server = Server("valid_token", connect=False, ) |
| def test_server(): | ||
| server = Server("valid_token", connect=False, ) | ||
| assert type(server) == Server | ||
| assert server == "valid_token" |
There was a problem hiding this comment.
the server is coerced into a string? is that a useful feature?
There was a problem hiding this comment.
No idea. It's a Preexisting Feature™
I've never used it, but I'm sure someone has at some point during the history of this project.
| assert userbyname != "someotheruser" | ||
| user_by_name = server.users.find('fakeuser') | ||
| assert type(user_by_name) == User | ||
| assert user_by_name == "fakeuser" |
There was a problem hiding this comment.
Users are coerced into a string? is that a useful feature?
There was a problem hiding this comment.
I'm especially worried about this because we'd like to de-emphasize programmatic usage of username.
There was a problem hiding this comment.
this is from a refactor of the "SearchList" class that allowed searching through the client's cache by username or user ID. I just cleaned up the names for readability.
tests/test_server.py
Outdated
| userbyid = server.users.find('invaliduser') | ||
| assert type(userbyid) != User | ||
| user_by_id = server.users.find('invaliduser') | ||
| assert type(user_by_id) != User |
There was a problem hiding this comment.
okay, its type isn't a user, but what is the type? maybe that's what the assertion should check.
There was a problem hiding this comment.
Made it check for None instead 👍
| json={"ok": False} | ||
| ) | ||
|
|
||
| with pytest.raises(SlackConnectionError) as e: |
There was a problem hiding this comment.
i'm not sure what this is meant to do. how i'm currently reading this: "when a SlackConnectionError happens, ping the server". what does this accomplish other than swallowing the error?
There was a problem hiding this comment.
In order to write assertions about raised exceptions, you can use pytest.raises as a context manager
https://docs.pytest.org/en/latest/assert.html#assertions-about-expected-exceptions
There was a problem hiding this comment.
okay, but there's no assertion about the error in the body
There was a problem hiding this comment.
maybe i misunderstood. server.ping() causes the error, then wrapping it in pytest.raises(ErrorName) asserts that the error occurred and it is of that type?
There was a problem hiding this comment.
Changed the call to rtm_connect instead of ping, to more accurately reflect what it's testing
| server.rtm_connect(auto_reconnect=True, reconnect=True, use_rtm_start=False) | ||
|
|
||
| for call in rsps.calls: | ||
| assert call.request.url in [ |
There was a problem hiding this comment.
can you explain how this test works? i don't see how the timeout could have been hit.
There was a problem hiding this comment.
Added more context to the test
There was a problem hiding this comment.
not sure i understand. what i see is connecting when the last_connected_at time is now will immediately cause another connection attempt. that sounds like the opposite of what your comment says should happen.
slackclient/client.py
Outdated
| try: | ||
| self.server.rtm_connect(use_rtm_start=with_team_state, **kwargs) | ||
| return True | ||
| if self.server.connected: |
There was a problem hiding this comment.
return self.server.connected
| response_body = self.server.api_call(method, timeout=timeout, **kwargs) | ||
| try: | ||
| result = json.loads(response_body) | ||
| except ValueError as json_decode_error: |
There was a problem hiding this comment.
Keep this up here so it's more clear what Errors you handle for which lines
There was a problem hiding this comment.
It was still there, just moved way down into the wrong scope...
slackclient/client.py
Outdated
| if method == 'im.open': | ||
| if "ok" in result and result["ok"]: | ||
| self.server.attach_channel(kwargs["user"], result["channel"]["id"]) | ||
| # If the call was for a `group` or `im` endpoint, attach the group data |
There was a problem hiding this comment.
I've found that inline comments like this are some combination of three things:
- A good sign to break out into a separate function
- Suggest better naming of variables
- Superfluous and potentially going to be out-of-date after a refactor
There was a problem hiding this comment.
Realized these could just reuse server.parse_channel_data is they were passed as a single-item array
slackclient/server.py
Outdated
| elif self.reconnect_attempt > 0: | ||
| # Back off after the the first attempt | ||
| if (time.time() - self.last_connected_at) < 180: | ||
| # Random offset to prevent stampeding reconnects of multiple RTM clients |
There was a problem hiding this comment.
Maybe call the variable backoff_offset_multiplyer and then you'll be covered and don't need the comment
slackclient/server.py
Outdated
| if self.reconnect_attempt == 5: | ||
| raise SlackConnectionError("RTM connection failed, reached max reconnects.") | ||
| elif self.reconnect_attempt > 0: | ||
| # Back off after the the first attempt |
There was a problem hiding this comment.
I'd add some debug logging in this chunk of the code like you did below, that also "cheats" and gives you a chance to add a little more documentation inline with the code
| json=rtm_start_fixture | ||
| ) | ||
|
|
||
| server.rtm_connect(auto_reconnect=True) |
There was a problem hiding this comment.
I think you want some tests that do rsps.add multiple times, so you can fail a few times and ensure you reconnect after N tries, right? (I might've missed this tho).
Essentially have ~3 rsps.add, the first two return a 4xx and then you get a 200 for the third. That'll prove your reconnect handles errors properly 💪
There was a problem hiding this comment.
This reconnect logic only tests for when the socket is disconnected, then reconnected. It's not handling connection retries. That's part of another project 😄
|
|
||
|
|
||
| def test_rtm_reconnect_timeout_recently_connected(server, rtm_start_fixture): | ||
| # If reconnected recently, server must wait to reconnect and increment the counter |
There was a problem hiding this comment.
Feel free to make these docstrings to tie these to the function for some python-y tooling.
slackclient/server.py
Outdated
| # If this is an auto reconnect, rate limit reconnect attempts | ||
| if self.auto_reconnect and reconnect: | ||
| # Raise a SlackConnectionError after 5 retries within 3 minutes | ||
| if self.reconnect_attempt == 5: |
There was a problem hiding this comment.
This feels like a value that shouldn't be hidden down here in the guts?
There was a problem hiding this comment.
I agree, but I'm not quite sure where else it could go 🤔
slackclient/server.py
Outdated
| # Random offset to prevent stampeding reconnects of multiple RTM clients | ||
| offset = random.randint(1, 4) | ||
| reconnect_timeout = (offset * self.reconnect_attempt * self.reconnect_attempt) | ||
| logging.debug("Reconnecting in {} seconds".format(reconnect_timeout)) |
There was a problem hiding this comment.
logging.debug("Reconnecting in %d seconds", reconnect_timeout)
* Added reconnect logic to RTM client * Added a lot more tests * updated RTM test fixture * Disable testing for 3.6 on Windows until 3.6.5 release due to a windows web socket bug: https://bugs.python.org/issue32394
* Added reconnect logic to RTM client * Added a lot more tests * updated RTM test fixture * Disable testing for 3.6 on Windows until 3.6.5 release due to a windows web socket bug: https://bugs.python.org/issue32394
Summary
Adds
auto_reconnectto RTMRequirements (place an
xin each[ ])