You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
6.3 KiB
146 lines
6.3 KiB
2 months ago
|
# License: Apache 2.0. See LICENSE file in root directory.
|
||
|
# Copyright(c) 2023 Intel Corporation. All Rights Reserved.
|
||
|
|
||
|
#test:donotrun:!dds
|
||
|
#test:retries:gha 2
|
||
|
|
||
|
from rspy import log, test
|
||
|
import pyrealdds as dds
|
||
|
dds.debug( log.is_debug_on() )
|
||
|
|
||
|
device_info = dds.message.device_info()
|
||
|
device_info.topic_root = 'server/device'
|
||
|
|
||
|
with test.remote.fork( nested_indent=None ) as remote:
|
||
|
if remote is None: # we're the fork
|
||
|
|
||
|
with test.closure( 'Start the server participant' ):
|
||
|
participant = dds.participant()
|
||
|
participant.init( 123, 'server' )
|
||
|
|
||
|
with test.closure( 'Create the server' ):
|
||
|
device_info.name = 'Some device'
|
||
|
s1p1 = dds.video_stream_profile( 9, dds.video_encoding.rgb, 10, 10 )
|
||
|
s1profiles = [s1p1]
|
||
|
s1 = dds.color_stream_server( 's1', 'sensor' )
|
||
|
s1.init_profiles( s1profiles, 0 )
|
||
|
server = dds.device_server( participant, device_info.topic_root )
|
||
|
server.init( [s1], [], {} )
|
||
|
|
||
|
with test.closure( 'Set up a control handler' ):
|
||
|
n_replies = 0
|
||
|
def _on_control( server, id, control, reply ):
|
||
|
# the control has already been output to debug by the calling code, as will the reply
|
||
|
global n_replies
|
||
|
n_replies += 1
|
||
|
reply['sequence'] = n_replies # to show that we've processed it
|
||
|
reply['nested-json'] = { 'more': True } # to show off
|
||
|
return True # otherwise the control will be flagged as error
|
||
|
subscription = server.on_control( _on_control )
|
||
|
|
||
|
raise StopIteration() # exit the 'with' statement
|
||
|
|
||
|
|
||
|
###############################################################################################################
|
||
|
# The client is a device from which we send controls
|
||
|
#
|
||
|
from dds import wait_for_devices
|
||
|
|
||
|
with test.closure( 'Start the client participant' ):
|
||
|
participant = dds.participant()
|
||
|
participant.init( 123, 'client' )
|
||
|
|
||
|
with test.closure( 'Wait for the device' ):
|
||
|
device_info.name = 'Device1'
|
||
|
device = dds.device( participant, device_info )
|
||
|
device.wait_until_ready()
|
||
|
|
||
|
with test.closure( 'Set up a notification handler' ):
|
||
|
n_replies = 0
|
||
|
notification_count = dict()
|
||
|
reply_count = dict()
|
||
|
notification_count[device.guid()] = 0
|
||
|
reply_count[device.guid()] = 0
|
||
|
import threading
|
||
|
notifications = threading.Event()
|
||
|
def expect_notifications( n=1 ):
|
||
|
global notifications, n_notifications
|
||
|
notifications.clear()
|
||
|
n_notifications = n
|
||
|
def _on_notification( device, id, notification ):
|
||
|
global notification_count, notifications, n_notifications
|
||
|
n_notifications -= 1
|
||
|
if n_notifications <= 0:
|
||
|
notifications.set()
|
||
|
notification_count[device.guid()] += 1
|
||
|
sample = notification.get( 'sample' )
|
||
|
if sample is None:
|
||
|
log.d( f'notification to {device}: {notification}' )
|
||
|
elif sample[0] == str(device.guid()):
|
||
|
log.d( f'reply to {device}' )
|
||
|
reply_count[device.guid()] += 1
|
||
|
else:
|
||
|
log.d( f'notification to {device}' )
|
||
|
notification_subscription = device.on_notification( _on_notification )
|
||
|
|
||
|
with test.closure( 'Send a notification that is not a reply' ):
|
||
|
dev1_notifications = notification_count[device.guid()]
|
||
|
dev1_replies = reply_count[device.guid()]
|
||
|
expect_notifications( 1 )
|
||
|
remote.run( 'server.publish_notification( { "id": "something" } )' )
|
||
|
notifications.wait( 3 )
|
||
|
test.check_equal( notification_count[device.guid()], dev1_notifications + 1 ) # notification
|
||
|
test.check_equal( reply_count[device.guid()], dev1_replies ) # not a reply
|
||
|
|
||
|
with test.closure( 'Set up a control sender' ):
|
||
|
server_sequence = 0
|
||
|
def control( device, json, n=1 ):
|
||
|
global server_sequence
|
||
|
server_sequence += 1
|
||
|
expect_notifications( n )
|
||
|
reply = device.send_control( json, True ) # Wait for reply
|
||
|
if test.check( reply.get('control') is not None ):
|
||
|
test.check_equal( reply['control']['id'], json['id'] )
|
||
|
else:
|
||
|
test.check_equal( reply['id'], json['id'] )
|
||
|
test.check_equal( reply['sequence'], server_sequence )
|
||
|
test.check_equal( reply['sample'][0], str(device.guid()) )
|
||
|
notifications.wait( 3 ) # We may get the reply before the other notifications are received
|
||
|
return reply
|
||
|
|
||
|
with test.closure( 'Send some controls' ):
|
||
|
control( device, { 'id': 'control' } )
|
||
|
control( device, { 'id': 'control-2' } )
|
||
|
|
||
|
with test.closure( 'Add a second device!' ):
|
||
|
device_info.name = 'Device2'
|
||
|
device2 = dds.device( participant, device_info )
|
||
|
notification_count[device2.guid()] = 0
|
||
|
reply_count[device2.guid()] = 0
|
||
|
notification2_subscription = device2.on_notification( _on_notification )
|
||
|
device2.wait_until_ready()
|
||
|
|
||
|
with test.closure( 'Controls generate notifications to all devices' ):
|
||
|
dev1_notifications = notification_count[device.guid()]
|
||
|
dev2_notifications = notification_count[device2.guid()]
|
||
|
control( device, { 'id': 'dev1' }, 2 )
|
||
|
test.check_equal( notification_count[device.guid()], dev1_notifications + 1 )
|
||
|
test.check_equal( notification_count[device2.guid()], dev2_notifications + 1 ) # both get notifications
|
||
|
control( device2, { 'id': 'dev2' }, 2 )
|
||
|
test.check_equal( notification_count[device.guid()], dev1_notifications + 2 )
|
||
|
test.check_equal( notification_count[device2.guid()], dev2_notifications + 2 )
|
||
|
|
||
|
with test.closure( 'But only one gets a reply' ):
|
||
|
dev1_replies = reply_count[device.guid()]
|
||
|
dev2_replies = reply_count[device2.guid()]
|
||
|
control( device, { 'id': 'dev1' }, 2 )
|
||
|
test.check_equal( reply_count[device.guid()], dev1_replies + 1 )
|
||
|
test.check_equal( reply_count[device2.guid()], dev2_replies )
|
||
|
control( device2, { 'id': 'dev2' }, 2 )
|
||
|
test.check_equal( reply_count[device.guid()], dev1_replies + 1 )
|
||
|
test.check_equal( reply_count[device2.guid()], dev2_replies + 1 )
|
||
|
|
||
|
device = None
|
||
|
|
||
|
test.print_results()
|