Skip to content

Commit 205a1cb

Browse files
track2 - servicebus - flaky test and documentation improvements for preview 3 (#11740)
* Fix flaky tests to be more robust by adding dynamic expiry timers, remove reliance on message abandon ordering, and add additional test for session message error handling. * Additionally adds a helpful note to the README on how to handle autolockrenew failure in response to customer feedback; and a note in the migration guide about message datetime timezone and naming changes. * Rename migration guide header and add additional sample for other object. Adjust test to use more normal constructs (iterator receive).
1 parent 80f56b8 commit 205a1cb

File tree

5 files changed

+35
-6
lines changed

5 files changed

+35
-6
lines changed

sdk/servicebus/azure-servicebus/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ link will extend this timeout.
228228
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.
229229
- 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.
230230

231+
### AutoLockRenew
232+
233+
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.
234+
It would also manifest when trying to take action (such as completing a message) on the specified object.
235+
231236
### Common Exceptions
232237

233238
Please view the [exceptions](./azure/servicebus/exceptions.py) file for detailed descriptions of our common Exception types.

sdk/servicebus/azure-servicebus/migration_guide.md

+6
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ semantics with the sender or receiver lifetime.
6464
| `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) |
6565
| `receiver.get_session_state()` | `receiver.session.get_session_state()` | [Perform session specific operations on a receiver](./samples/sync_samples/session_send_receive.py)
6666

67+
### Working with UTC time
68+
| In v0.50 | Equivalent in v7 | Note |
69+
|---|---|---|
70+
| `session.locked_until < datetime.now()`| `session.locked_until_utc < datetime.utcnow()`| All datetimes are now UTC and named as such|
71+
| `message.scheduled_enqueue_time < datetime.now()`| `message.scheduled_enqueue_time_utc < datetime.utcnow()`| UTC Datetime normalization applies across all objects and datetime fields|
72+
6773
## Migration samples
6874

6975
* [Receiving messages](#migrating-code-from-queueclient-and-receiver-to-servicebusreceiver-for-receiving-messages)

sdk/servicebus/azure-servicebus/tests/async_tests/test_queues_async.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ async def test_async_queue_by_servicebus_client_renew_message_locks(self, servic
675675
finally:
676676
await messages[0].complete()
677677
await messages[1].complete()
678-
time.sleep(30)
678+
sleep_until_expired(messages[2])
679679
with pytest.raises(MessageLockExpired):
680680
await messages[2].complete()
681681

sdk/servicebus/azure-servicebus/tests/test_queues.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ def test_queue_by_servicebus_client_renew_message_locks(self, servicebus_namespa
766766
messages[0].complete()
767767
messages[1].complete()
768768
assert (messages[2].locked_until_utc - utc_now()) <= timedelta(seconds=60)
769-
time.sleep((messages[2].locked_until_utc - utc_now()).total_seconds())
769+
sleep_until_expired(messages[2])
770770
with pytest.raises(MessageLockExpired):
771771
messages[2].complete()
772772

sdk/servicebus/azure-servicebus/tests/test_sessions.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
MessageLockExpired,
2626
MessageAlreadySettled,
2727
AutoLockRenewTimeout,
28-
MessageSettleFailed)
28+
MessageSettleFailed,
29+
MessageSendFailed)
2930

3031
from devtools_testutils import AzureMgmtTestCase, CachedResourceGroupPreparer
3132
from servicebus_preparer import (
@@ -903,12 +904,15 @@ def test_session_by_session_client_conn_str_receive_handler_peeklock_abandon(sel
903904
message = Message("Handler message no. {}".format(i), session_id=session_id)
904905
sender.send(message)
905906

906-
with sb_client.get_queue_session_receiver(servicebus_queue.name, session_id=session_id, prefetch=0) as receiver:
907+
with sb_client.get_queue_session_receiver(servicebus_queue.name, session_id=session_id, prefetch=0, idle_timeout=5) as receiver:
907908
message = receiver.next()
908909
assert message.sequence_number == 1
909910
message.abandon()
910-
second_message = receiver.next()
911-
assert second_message.sequence_number == 1
911+
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.
912+
if not next_message:
913+
raise Exception("Did not successfully re-receive abandoned message, sequence_number 1 was not observed.")
914+
if next_message.sequence_number == 1:
915+
return
912916

913917
@pytest.mark.liveTest
914918
@pytest.mark.live_test_only
@@ -937,3 +941,17 @@ def test_session_basic_topic_subscription_send_and_receive(self, servicebus_name
937941
message.complete()
938942
assert count == 1
939943

944+
945+
@pytest.mark.liveTest
946+
@pytest.mark.live_test_only
947+
@CachedResourceGroupPreparer(name_prefix='servicebustest')
948+
@CachedServiceBusNamespacePreparer(name_prefix='servicebustest')
949+
@ServiceBusQueuePreparer(name_prefix='servicebustest', requires_session=True)
950+
def test_session_non_session_send_to_session_queue_should_fail(self, servicebus_namespace_connection_string, servicebus_queue, **kwargs):
951+
with ServiceBusClient.from_connection_string(
952+
servicebus_namespace_connection_string, logging_enable=False) as sb_client:
953+
954+
with sb_client.get_queue_sender(servicebus_queue.name) as sender:
955+
message = Message("This should be an invalid non session message")
956+
with pytest.raises(MessageSendFailed):
957+
sender.send(message)

0 commit comments

Comments
 (0)