Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pymongo/asynchronous/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,8 @@ async def _hello(
hello.logical_session_timeout_minutes is not None and hello.is_readable
)
self.logical_session_timeout_minutes: Optional[int] = hello.logical_session_timeout_minutes
self.hello_ok = hello.hello_ok
# PYTHON-5904

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you make this comment a little more informative rather than just the ticket name?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

no problem.

self.hello_ok = self.hello_ok or hello.hello_ok
self.is_repl = hello.server_type in (
SERVER_TYPE.RSPrimary,
SERVER_TYPE.RSSecondary,
Expand Down
83 changes: 83 additions & 0 deletions test/asynchronous/test_hello_latched.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Copyright 2022-present MongoDB, Inc.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
# Copyright 2022-present MongoDB, Inc.
# Copyright 2026-present MongoDB, Inc.

#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test that connection continues to use hello after ismaster returns hello_ok"""

import unittest

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Needs the standard license header, see another test file for an example.

from unittest.mock import AsyncMock
from types import SimpleNamespace
from pymongo.asynchronous.pool import AsyncConnection

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The line _IS_SYNC = False needs to be here after the imports.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

No worries, I will make these changes.
Thanks Noah.

class TestHelloLatched(unittest.IsolatedAsyncioTestCase):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
class TestHelloLatched(unittest.IsolatedAsyncioTestCase):
class TestHelloLatched(AsyncUnitTest):


def setUp(self):
self._sent = []

def create_connection(self) -> AsyncConnection:
"""Returns a minimal connection object for _hello"""
conn = object.__new__(AsyncConnection)
conn.hello_ok = False
conn.performed_handshake = True
conn.opts = SimpleNamespace(
server_api = None,
load_balanced = False,
_credentials = None
)

return conn

async def mock_conn_command(self, db, cmd, **kwargs):
"""Returns mocked hello and ismaster results for conn.command"""
self._sent.append(cmd.copy())
if cmd.get("ismaster") == 1:
return {"ok":1, "helloOk": True, "ismaster": True, "maxWireVersion": 25}
return {"ok":1, "isWritablePrimary": True, "maxWireVersion": 25}


async def test_hello_is_latched(self):
"""
Regression Test for PYTHON-5904
Tests for connection hello_ok persistence when connection
Switches from ismaster to hello
"""
conn = self.create_connection()
conn.command = AsyncMock(side_effect=self.mock_conn_command)

# First hello
await conn._hello(None, None)
# Verify hello_ok is True
self.assertTrue(conn.hello_ok)
# Verify command sent is ismaster
self.assertEqual(self._sent[0].get("ismaster"), 1)
self.assertEqual(self._sent[0].get("helloOk"), True)

# Second hello
await conn._hello(None, None)
# Verify hello_ok has not changed
self.assertTrue(conn.hello_ok)
# Verify command sent is hello
self.assertEqual(self._sent[1].get("hello"), 1)
self.assertIsNone(self._sent[1].get("ismaster", None))

# Third hello
await conn._hello(None, None)
# Verify connection continues to use hello
self.assertEqual(self._sent[2].get("hello"), 1)
self.assertIsNone(self._sent[2].get("ismaster", None))


if __name__ == "__main__":
unittest.main()