diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 53f78b0a..c1be2ada 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -46,4 +46,4 @@ jobs: - name: Generate rest sync code and tests run: uv run unasync - name: Test with pytest - run: uv run pytest --verbose --tb=short --reruns 3 + run: uv run pytest -s --verbose --tb=short --reruns 3 diff --git a/ably/realtime/realtimepresence.py b/ably/realtime/realtimepresence.py index 2702846d..78a97cf2 100644 --- a/ably/realtime/realtimepresence.py +++ b/ably/realtime/realtimepresence.py @@ -470,7 +470,7 @@ async def subscribe(self, *args) -> None: """ # RTP6d: Implicitly attach if self.channel.state in [ChannelState.INITIALIZED, ChannelState.DETACHED, ChannelState.DETACHING]: - asyncio.create_task(self.channel.attach()) + await self.channel.attach() # Parse arguments: similar to channel subscribe if len(args) == 1: diff --git a/test/ably/realtime/realtimepresence_test.py b/test/ably/realtime/realtimepresence_test.py index e7073983..28d98cc0 100644 --- a/test/ably/realtime/realtimepresence_test.py +++ b/test/ably/realtime/realtimepresence_test.py @@ -35,24 +35,26 @@ class TestRealtimePresenceBasics(BaseAsyncTestCase): """Test basic presence operations: enter, leave, update.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance - self.client1 = await TestApp.get_ably_realtime( + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol + + test_instance.client1 = await TestApp.get_ably_realtime( client_id='client1', use_binary_protocol=use_binary_protocol ) - self.client2 = await TestApp.get_ably_realtime( + test_instance.client2 = await TestApp.get_ably_realtime( client_id='client2', use_binary_protocol=use_binary_protocol ) yield - await self.client1.close() - await self.client2.close() + await test_instance.client1.close() + await test_instance.client2.close() async def test_presence_enter_without_attach(self): """ @@ -188,24 +190,26 @@ class TestRealtimePresenceGet(BaseAsyncTestCase): """Test presence.get() functionality.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance + + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol - self.client1 = await TestApp.get_ably_realtime( + test_instance.client1 = await TestApp.get_ably_realtime( client_id='client1', use_binary_protocol=use_binary_protocol ) - self.client2 = await TestApp.get_ably_realtime( + test_instance.client2 = await TestApp.get_ably_realtime( client_id='client2', use_binary_protocol=use_binary_protocol ) yield - await self.client1.close() - await self.client2.close() + await test_instance.client1.close() + await test_instance.client2.close() async def test_presence_enter_get(self): """ @@ -282,24 +286,32 @@ class TestRealtimePresenceSubscribe(BaseAsyncTestCase): """Test presence.subscribe() functionality.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + protocol = 'msgpack' if use_binary_protocol else 'json' + test_instance = request.instance + print(f"[{protocol}] FIXTURE: request.instance = {test_instance}, id = {id(test_instance) if test_instance else 'None'}") + + if test_instance is None: + raise RuntimeError(f"[{protocol}] FIXTURE ERROR: request.instance is None!") - self.client1 = await TestApp.get_ably_realtime( + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol + + test_instance.client1 = await TestApp.get_ably_realtime( client_id='client1', use_binary_protocol=use_binary_protocol ) - self.client2 = await TestApp.get_ably_realtime( + + test_instance.client2 = await TestApp.get_ably_realtime( client_id='client2', use_binary_protocol=use_binary_protocol ) yield - await self.client1.close() - await self.client2.close() + await test_instance.client1.close() + await test_instance.client2.close() async def test_presence_subscribe_unattached(self): """ @@ -348,7 +360,9 @@ def on_presence(msg): await channel1.presence.enter() msg = await asyncio.wait_for(received, timeout=5.0) - assert msg.action == PresenceAction.ENTER + # RTP8c: Should receive ENTER action since we're entering for the first time + assert msg.action == PresenceAction.ENTER, \ + f"Expected ENTER action, got {msg.action}" @pytest.mark.parametrize('use_binary_protocol', [True, False], ids=['msgpack', 'json']) @@ -356,20 +370,22 @@ class TestRealtimePresenceEnterClient(BaseAsyncTestCase): """Test enterClient/updateClient/leaveClient functionality.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance + + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol # Use wildcard auth for enterClient - self.client = await TestApp.get_ably_realtime( + test_instance.client = await TestApp.get_ably_realtime( client_id='*', use_binary_protocol=use_binary_protocol ) yield - await self.client.close() + await test_instance.client.close() async def test_enter_client_multiple(self): """ @@ -441,10 +457,12 @@ class TestRealtimePresenceConnectionLifecycle(BaseAsyncTestCase): """Test presence behavior during connection lifecycle events.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance + + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol yield async def test_presence_enter_without_connect(self): @@ -569,10 +587,12 @@ class TestRealtimePresenceAutoReentry(BaseAsyncTestCase): """Test automatic re-entry of presence after connection suspension.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance + + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol yield async def test_presence_auto_reenter_after_suspend(self): @@ -728,10 +748,12 @@ class TestRealtimePresenceSyncBehavior(BaseAsyncTestCase): """Test presence SYNC behavior and state management.""" @pytest.fixture(autouse=True) - async def setup(self, use_binary_protocol): + async def setup(self, use_binary_protocol, request): """Set up test fixtures.""" - self.test_vars = await TestApp.get_test_vars() - self.use_binary_protocol = use_binary_protocol + test_instance = request.instance + + test_instance.test_vars = await TestApp.get_test_vars() + test_instance.use_binary_protocol = use_binary_protocol yield async def test_presence_refresh_on_detach(self):