diff --git a/sdk/servicebus/azure-servicebus/README.md b/sdk/servicebus/azure-servicebus/README.md index 400409f8593..c25374a1f43 100644 --- a/sdk/servicebus/azure-servicebus/README.md +++ b/sdk/servicebus/azure-servicebus/README.md @@ -228,6 +228,11 @@ link will extend this timeout. a generator-style receive will run for before exiting if there are no messages. Passing None (default) will wait forever, up until the 10 minute threshold if no other action is taken. - max_wait_time: Provided when calling receive() to fetch a batch of messages. Dictates how long the receive() will wait for more messages before returning, similarly up to the aformentioned limits. +### AutoLockRenew + +If for any reason auto-renewal has been interrupted or failed, this can be observed via the `auto_renew_error` property on the object being renewed. +It would also manifest when trying to take action (such as completing a message) on the specified object. + ### Common Exceptions Please view the [exceptions](./azure/servicebus/exceptions.py) file for detailed descriptions of our common Exception types. diff --git a/sdk/servicebus/azure-servicebus/migration_guide.md b/sdk/servicebus/azure-servicebus/migration_guide.md index cc2ad347388..549f0afd2f5 100644 --- a/sdk/servicebus/azure-servicebus/migration_guide.md +++ b/sdk/servicebus/azure-servicebus/migration_guide.md @@ -64,6 +64,12 @@ semantics with the sender or receiver lifetime. | `AutoLockRenew().register(queue_client.get_receiver(session='foo'))`| `AutoLockRenew().register(sb_client.get_queue_session_receiver(session_id='foo').session)`| [Access a session and ensure its lock is auto-renewed](./samples/sync_samples/session_send_receive.py) | | `receiver.get_session_state()` | `receiver.session.get_session_state()` | [Perform session specific operations on a receiver](./samples/sync_samples/session_send_receive.py) +### Working with UTC time +| In v0.50 | Equivalent in v7 | Note | +|---|---|---| +| `session.locked_until < datetime.now()`| `session.locked_until_utc < datetime.utcnow()`| All datetimes are now UTC and named as such| +| `message.scheduled_enqueue_time < datetime.now()`| `message.scheduled_enqueue_time_utc < datetime.utcnow()`| UTC Datetime normalization applies across all objects and datetime fields| + ## Migration samples * [Receiving messages](#migrating-code-from-queueclient-and-receiver-to-servicebusreceiver-for-receiving-messages) diff --git a/sdk/servicebus/azure-servicebus/tests/async_tests/test_queues_async.py b/sdk/servicebus/azure-servicebus/tests/async_tests/test_queues_async.py index 13b7e3d453e..3958b1b82cc 100644 --- a/sdk/servicebus/azure-servicebus/tests/async_tests/test_queues_async.py +++ b/sdk/servicebus/azure-servicebus/tests/async_tests/test_queues_async.py @@ -659,7 +659,7 @@ async def test_async_queue_by_servicebus_client_renew_message_locks(self, servic finally: await messages[0].complete() await messages[1].complete() - time.sleep(30) + sleep_until_expired(messages[2]) with pytest.raises(MessageLockExpired): await messages[2].complete() diff --git a/sdk/servicebus/azure-servicebus/tests/test_queues.py b/sdk/servicebus/azure-servicebus/tests/test_queues.py index bf6dc50dce6..6912acd652d 100644 --- a/sdk/servicebus/azure-servicebus/tests/test_queues.py +++ b/sdk/servicebus/azure-servicebus/tests/test_queues.py @@ -785,7 +785,7 @@ def test_queue_by_servicebus_client_renew_message_locks(self, servicebus_namespa messages[0].complete() messages[1].complete() assert (messages[2].locked_until_utc - utc_now()) <= timedelta(seconds=60) - time.sleep((messages[2].locked_until_utc - utc_now()).total_seconds()) + sleep_until_expired(messages[2]) with pytest.raises(MessageLockExpired): messages[2].complete() diff --git a/sdk/servicebus/azure-servicebus/tests/test_sessions.py b/sdk/servicebus/azure-servicebus/tests/test_sessions.py index e27c07fc5f8..4a0d2cc764e 100644 --- a/sdk/servicebus/azure-servicebus/tests/test_sessions.py +++ b/sdk/servicebus/azure-servicebus/tests/test_sessions.py @@ -25,7 +25,8 @@ MessageLockExpired, MessageAlreadySettled, AutoLockRenewTimeout, - MessageSettleFailed) + MessageSettleFailed, + MessageSendFailed) from devtools_testutils import AzureMgmtTestCase, CachedResourceGroupPreparer from servicebus_preparer import ( @@ -908,12 +909,15 @@ def test_session_by_session_client_conn_str_receive_handler_peeklock_abandon(sel message = Message("Handler message no. {}".format(i), session_id=session_id) sender.send(message) - with sb_client.get_queue_session_receiver(servicebus_queue.name, session_id=session_id, prefetch=0) as receiver: + with sb_client.get_queue_session_receiver(servicebus_queue.name, session_id=session_id, prefetch=0, idle_timeout=5) as receiver: message = receiver.next() assert message.sequence_number == 1 message.abandon() - second_message = receiver.next() - assert second_message.sequence_number == 1 + for next_message in receiver: # we can't be sure there won't be a service delay, so we may not get the message back _immediately_, even if in most cases it shows right back up. + if not next_message: + raise Exception("Did not successfully re-receive abandoned message, sequence_number 1 was not observed.") + if next_message.sequence_number == 1: + return @pytest.mark.liveTest @pytest.mark.live_test_only @@ -942,3 +946,17 @@ def test_session_basic_topic_subscription_send_and_receive(self, servicebus_name message.complete() assert count == 1 + + @pytest.mark.liveTest + @pytest.mark.live_test_only + @CachedResourceGroupPreparer(name_prefix='servicebustest') + @CachedServiceBusNamespacePreparer(name_prefix='servicebustest') + @ServiceBusQueuePreparer(name_prefix='servicebustest', requires_session=True) + def test_session_non_session_send_to_session_queue_should_fail(self, servicebus_namespace_connection_string, servicebus_queue, **kwargs): + with ServiceBusClient.from_connection_string( + servicebus_namespace_connection_string, logging_enable=False) as sb_client: + + with sb_client.get_queue_sender(servicebus_queue.name) as sender: + message = Message("This should be an invalid non session message") + with pytest.raises(MessageSendFailed): + sender.send(message)