Skip to content
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

refactor: upgrade all integration tests to asyncio async await #667

Merged
merged 21 commits into from
Apr 19, 2024

Conversation

taddes
Copy link
Contributor

@taddes taddes commented Mar 23, 2024

Closes SYNC-4120

@taddes taddes self-assigned this Mar 23, 2024
@taddes taddes marked this pull request as draft March 23, 2024 01:07
@taddes
Copy link
Contributor Author

taddes commented Mar 25, 2024

sentry output test failure only occurring in CI. Investigating why it raises RuntimeError('Event loop is closed')

@taddes taddes force-pushed the refactor/SYNC-4120_upgrade_core_test_asyncio branch from 2c2c84a to 9ac75e6 Compare April 1, 2024 14:07
@taddes taddes force-pushed the refactor/SYNC-4120_upgrade_core_test_asyncio branch from cafe340 to 6356666 Compare April 8, 2024 18:02
@taddes taddes force-pushed the refactor/SYNC-4120_upgrade_core_test_asyncio branch from 2698ca2 to bc577c9 Compare April 16, 2024 17:24
@taddes taddes marked this pull request as ready for review April 16, 2024 21:34
@taddes taddes requested review from pjenvey and jrconlin April 16, 2024 21:34
Comment on lines +582 to 583
class TestRustWebPush:
"""Test class for Rust Web Push."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can get rid of this class and use pytest fixtures but we can do that later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jrbenny35 absolutely! That's the next ticket once this is done and am very excited to have fixtures over the class. Thanks for chiming in!

@taddes taddes force-pushed the refactor/SYNC-4120_upgrade_core_test_asyncio branch from 48f698c to 9413df5 Compare April 18, 2024 20:26
Comment on lines 240 to 241
res = await object.__getattribute__(self, "get_notification")(timeout)
return res
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this might have been used for debugging at some point previously but we might as well reduce the diff (same for the end of the ping method)

Suggested change
res = await object.__getattribute__(self, "get_notification")(timeout)
return res
return await object.__getattribute__(self, "get_notification")(timeout)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call @pjenvey . Relatedly, was it in convo with you or @jrconlin that it was suggested the "get_notification" calls be made explicitly instead of in this 'clever' way, since I know when I first saw it and looked at the resultant return values in the tests that it was a bit baffling at first.

yield client.hello()
yield client.send_bad_data()
yield self.shut_down(client)
TestRustWebPush.clear_sentry_queue()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably kill these additional clears in all the sentry test methods with the flake issue resolved, letting tearDown handle it

Suggested change
TestRustWebPush.clear_sentry_queue()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally. Will move into the pytest setup/teardown fixture in the next PR so it conforms to pytest and not this unittest artifact.


# LogCheck does throw an error every time
httpx.get(f"http://localhost:{CONNECTION_PORT}/v1/err/crit", timeout=30)
async with httpx.AsyncClient() as httpx_client:
await httpx_client.get(f"http://localhost:{CONNECTION_PORT}/v1/err/crit", timeout=30)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll note that I doubt we actually need a longer timeout=30 in these sentry tests but this is from the original code, so keeping it is fine.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep the 30s timeout, if only because CI can be a bit flakey or slow and I'm fine if we don't accidentally timeout and fail the test. If the client responds faster, all the better.

assert sorted(values) == ["ERROR:Success", "LogCheck"]

@pytest.mark.order(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is pytest-order still necessary (if not I'm inclined to remove it)?

@@ -41,6 +41,9 @@ add-select = ["D212"]
# D400 First line should end with a period, doesn't work when sentence spans 2 lines
add-ignore = ["D105","D107","D203", "D205", "D400"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like this mode means we don't need to decorate tests with any @pytest.mark.asyncio markers? If so that SGTM: let's get rid of them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was on the fence about this. While the auto feature is nice, it's not very explicit and gets into "magic" territory with testing (like other annoying stuff like root-test dir defined fixtures in a conftest that pollute the namespace by magically appearing in tests as arguments with 0 context), which I am not a fan of.

It's not immediately evident that the async event loop pytest-asyncio provides is used unless one goes digging in the config. I know in projects I've worked on when random configs are defined with side effects like that, it can lead to confusion. What do you think? It would be nicer not to have to annotate with so many @pytest.mark.asyncio decorators, yet something about the explicit nature seemed sensible. Definitely on point that we shouldn't have both. WDYT? For now I just took the config out but can switch it around.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I'm fine w/ either way

"""Clear any values present in Sentry queue."""
while not MOCK_SENTRY_QUEUE.empty():
MOCK_SENTRY_QUEUE.get_nowait()
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return


@inlineCallbacks
def quick_register(self):
@pytest.mark.asyncio
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regardless of asyncio auto mode or not, this and shut_down shouldn't be decorated w/ @pytest.mark.asyncio as they're not tests

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch 👍

future that returns the expected float latency value.
"""
client = await self.quick_register()
result = await client.ping()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't familiar with the websockets ping API so this confused me a bit: could we rename this result to pong_waiter like their example, and/or note in the method docstring we're awaiting a pong response.

@taddes taddes force-pushed the refactor/SYNC-4120_upgrade_core_test_asyncio branch from 37b27e7 to 334f4f8 Compare April 19, 2024 18:44
@taddes taddes requested a review from pjenvey April 19, 2024 18:56
@taddes taddes requested a review from pjenvey April 19, 2024 19:33
result = await self.ws.recv()
log.debug(f"Recv: {result}")
return result

async def ping(self):
"""Test ping/pong request and respose of websocket.
A ping may serve as a keepalive or as a check that the remote endpoint received.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
A ping may serve as a keepalive or as a check that the remote endpoint received.
A ping may serve as a keepalive or as a check that the remote is continuing to respond to websocket protocol messages.

result = await self.ws.recv()
log.debug(f"Recv: {result}")
return result

async def ping(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really sure that this is necessary, since it's testing an aspect of the Websocket protocol, not our implementation of Web Push but 🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you are right, don't necessarily need it. I can remove


# LogCheck does throw an error every time
httpx.get(f"http://localhost:{CONNECTION_PORT}/v1/err/crit", timeout=30)
async with httpx.AsyncClient() as httpx_client:
await httpx_client.get(f"http://localhost:{CONNECTION_PORT}/v1/err/crit", timeout=30)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep the 30s timeout, if only because CI can be a bit flakey or slow and I'm fine if we don't accidentally timeout and fail the test. If the client responds faster, all the better.

@jrconlin
Copy link
Member

Thank you for all the work on this. It's awesome.

@taddes
Copy link
Contributor Author

taddes commented Apr 19, 2024

Thanks so much @jrconlin ❤️

@taddes taddes changed the title Upgrade all integration tests to asyncio async await refactor: upgrade all integration tests to asyncio async await Apr 19, 2024
@taddes taddes merged commit c7448f4 into master Apr 19, 2024
1 check passed
@taddes taddes deleted the refactor/SYNC-4120_upgrade_core_test_asyncio branch April 19, 2024 21:48
@pjenvey
Copy link
Member

pjenvey commented Apr 19, 2024

One last thing I forgot to mention: these changes added a few new warnings to the test suite, we should log an issue to take a pass/attempt to quiet them (if possible)

@taddes
Copy link
Contributor Author

taddes commented Apr 20, 2024

Yes @pjenvey , was going to do just that. It's those intermittent socket disconnection warnings which I think are a byproduct of the new library. I'll file the ticket for that and will look at it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants