${text} = TemplatedRequests.Post_To_Uri uri=${uri} data=${EMPTY} accept=${ACCEPT_JSON} content_type=${HEADERS_YANG_JSON} session=${session}
Publish_Notifications
- [Arguments] ${member_index} ${seconds} ${notif_per_sec}
- [Documentation] TODO: more desctiptive comment than: Invoke publish-notifications rpc.
+ [Arguments] ${member_index} ${gid} ${seconds} ${notif_per_sec}
+ [Documentation] Start publishing notifications by invoking publish-notifications rpc. This call is blocking
+ ... and it returns when publishing is over. It suppose to take as long as ${seconds}.
${session} = ClusterManagement.Resolve_Http_Session_For_Member member_index=${member_index}
- &{mapping} BuiltIn.Create_Dictionary SECONDS=${seconds} NPS=${notif_per_sec}
+ &{mapping} BuiltIn.Create_Dictionary ID=${gid} DURATION=${seconds} RATE=${notif_per_sec}
TemplatedRequests.Post_As_Xml_Templated ${PUBLISH_NOTIFICATIONS_DIR} mapping=${mapping} session=${session}
Subscribe_Ynl
- [Arguments] ${member_index}
- [Documentation] TODO: more desctiptive comment than: Invoke subscribe-ynl rpc.
+ [Arguments] ${member_index} ${gid}
+ [Documentation] Subscribe listener for the notifications with identifier ${gid}.
${session} = ClusterManagement.Resolve_Http_Session_For_Member member_index=${member_index}
- &{mapping} BuiltIn.Create_Dictionary
+ &{mapping} BuiltIn.Create_Dictionary ID=${gid}
TemplatedRequests.Post_As_Xml_Templated ${SUBSCRIBE_YNL_DIR} mapping=${mapping} session=${session}
Unsubscribe_Ynl
- [Arguments] ${member_index}
- [Documentation] TODO: more desctiptive comment than: Invoke unsubscribe-ynl rpc.
+ [Arguments] ${member_index} ${gid}
+ [Documentation] Unsubscribe listener for the ${gid} identifier. Return statistics of the publishing process.
${session} = ClusterManagement.Resolve_Http_Session_For_Member member_index=${member_index}
- &{mapping} BuiltIn.Create_Dictionary
+ &{mapping} BuiltIn.Create_Dictionary ID=${gid}
${text} = TemplatedRequests.Post_As_Xml_Templated ${UNSUBSCRIBE_YNL_DIR} mapping=${mapping} session=${session}
+ ${xml} = XML.Parse_Xml ${text}
+ ${all_not} = XML.Get_Element_Text ${xml} xpath=all-not
+ ${id_not} = XML.Get_Element_Text ${xml} xpath=id-not
+ ${err_not} = XML.Get_Element_Text ${xml} xpath=err-not
+ ${local_number} = XML.Get_Element_Text ${xml} xpath=local-number
+ BuiltIn.Return_From_Keyword ${all_not} ${id_not} ${err_not} ${local_number}
Register_Bound_Constant
[Arguments] ${member_index} ${context} ${constant}
--- /dev/null
+"""
+Python invocation of several parallel publish-notifications RPCs.
+"""
+import Queue
+import requests
+import string
+import threading
+
+
+def publish_notifications(host, grprefix, duration, rate, nrpairs=1):
+ """Invoke publish notification rpcs and verify the response.
+
+ :param host: ip address of odl node
+ :type host: string
+ :param grprefix: prefix identifier for publisher/listener pair
+ :type grprefix: string
+ :param duration: publishing notification duration in seconds
+ :type duration: int
+ :param rate: events rate per second
+ :type rate: int
+ :param nrpairs: number of publisher/listener pairs, id suffix is counted from it
+ :type nrpairs: int
+ """
+ def _publ_notifications(rqueue, url, grid, duration, rate):
+ dtmpl = string.Template('''<input xmlns="tag:opendaylight.org,2017:controller:yang:lowlevel:control">
+ <id>$ID</id>
+ <seconds>$DURATION</seconds>
+ <notifications-per-second>$RATE</notifications-per-second>
+</input>''')
+ data = dtmpl.substitute({'ID': grid, 'DURATION': duration, 'RATE': rate})
+ try:
+ resp = requests.post(url=url, headers={'Content-Type': 'application/xml'},
+ data=data, auth=('admin', 'admin'), timeout=int(duration)+60)
+ except Exception as exc:
+ resp = exc
+ rqueue.put(resp)
+
+ resqueue = Queue.Queue()
+ lthreads = []
+ url = 'http://{}:8181/restconf/operations/odl-mdsal-lowlevel-control:publish-notifications'.format(host)
+ for i in range(nrpairs):
+ t = threading.Thread(target=_publ_notifications,
+ args=(resqueue, url, '{}{}'.format(grprefix, i+1), duration, rate))
+ t.daemon = True
+ t.start()
+ lthreads.append(t)
+
+ for t in lthreads:
+ t.join()
+
+ for i in range(nrpairs):
+ resp = resqueue.get()
+ assert resp.status_code == 200
--- /dev/null
+*** Settings ***
+Documentation DOMNotificationBroker testing: Common keywords
+...
+... Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+Library ${CURDIR}/../MdsalLowlevelPy.py
+Resource ${CURDIR}/../MdsalLowlevel.robot
+
+*** Variables ***
+${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE} ${5000}
+${DNB_PUBLISHER_LISTENER_PREFIX} working-pair-
+${DNB_TESTED_MEMBER_INDEX} 1
+
+*** Keywords ***
+Dom_Notification_Broker_Test_Templ
+ [Arguments] ${total_notification_rate} ${test_duration_in_seconds}
+ [Documentation] Test case template. Input parameter ${total_notification_rate} determines, how many publisher/subscriber
+ ... pais take part in the test case. For every ${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE} one pair is created.
+ ... The test case itself firstly subscribe listeners, then run publishers and at the end unsubscribe listeners
+ ... and check achieved rates.
+ BuiltIn.Log Overall requested rate: ${total_notification_rate}, test duration: ${test_duration_in_seconds} seconds.
+ ${count} = BuiltIn.Set_variable ${0}
+ : FOR ${suffix} IN RANGE ${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE} ${total_notification_rate}+1 ${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE}
+ \ ${count} = BuiltIn.Evaluate ${count}+1
+ \ MdsalLowlevel.Subscribe_Ynl ${DNB_TESTED_MEMBER_INDEX} ${DNB_PUBLISHER_LISTENER_PREFIX}${count}
+ ${count} = BuiltIn.Convert_To_Integer ${count}
+ MdsalLowlevelPy.Publish_Notifications ${ODL_SYSTEM_${DNB_TESTED_MEMBER_INDEX}_IP} ${DNB_PUBLISHER_LISTENER_PREFIX} ${test_duration_in_seconds} ${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE} nrpairs=${count}
+ ${sum_local_number} BuiltIn.Set_Variable ${0}
+ ${low_limit_pair_rate} = BuiltIn.Evaluate 0.9*${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE}
+ ${high_limit_pair_rate} = BuiltIn.Evaluate 1.1*${DNB_PUBLISHER_SUBSCRIBER_PAIR_RATE}
+ : FOR ${index} IN RANGE 1 ${count}+1
+ \ ${all_not} ${id_not} ${err_not} ${local_number} = MdsalLowlevel.Unsubscribe_Ynl ${DNB_TESTED_MEMBER_INDEX}
+ \ ... ${DNB_PUBLISHER_LISTENER_PREFIX}${index}
+ \ BuiltIn.Should_Be_Equal_As_Numbers ${err_not} ${0}
+ \ BuiltIn.Should_Not_Be_Equal_As_Numbers ${local_number} ${0}
+ \ BuiltIn.Should_Be_Equal_As_Numbers ${id_not} ${local_number}
+ \ ${rate} = BuiltIn.Evaluate ${local_number}/${test_duration_in_seconds}
+ \ BuiltIn.Should_Be_True ${rate} > ${low_limit_pair_rate}
+ \ BuiltIn.Should_Be_True ${rate} < ${high_limit_pair_rate}
+ \ ${sum_local_number} = BuiltIn.Evaluate ${sum_local_number}+${local_number}
+ ${final_rate} = BuiltIn.Evaluate ${sum_local_number}/${test_duration_in_seconds}
+ ${low_limit_final_rate} = BuiltIn.Evaluate 0.9*${total_notification_rate}
+ ${high_limit_final_rate} = BuiltIn.Evaluate 1.1*${total_notification_rate}
+ BuiltIn.Should_Be_True ${final_rate} > ${low_limit_final_rate}
+ BuiltIn.Should_Be_True ${final_rate} < ${high_limit_final_rate}
--- /dev/null
+*** Settings ***
+Documentation DOMNotificationBroker testing: No-loss rate
+...
+... Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+...
+... This program and the accompanying materials are made available under the
+... terms of the Eclipse Public License v1.0 which accompanies this distribution,
+... and is available at http://www.eclipse.org/legal/epl-v10.html
+...
+... Provides routing of YANG notifications from publishers to subscribers.
+... The purpose of this test is to determine the broker can forward messages without
+... loss. We do this on a single-node setup by incrementally adding publishers and
+... subscribers.
+Suite Setup SetupUtils.Setup_Utils_For_Setup_And_Teardown
+Suite Teardown SSHLibrary.Close_All_Connections
+Test Setup SetupUtils.Setup_Test_With_Logging_And_Without_Fast_Failing
+Test Teardown SetupUtils.Teardown_Test_Show_Bugs_If_Test_Failed
+Default Tags critical
+Test Template DnbCommons.Dom_Notification_Broker_Test_Templ
+Library SSHLibrary
+Resource ${CURDIR}/../../../libraries/controller/DnbCommons.robot
+Resource ${CURDIR}/../../../libraries/MdsalLowlevel.robot
+Resource ${CURDIR}/../../../libraries/SetupUtils.robot
+
+*** Variables ***
+${TC_DURATION_IN_SECONDS} ${300}
+
+*** Test Cases ***
+Notifications_rate_5k
+ ${5000} ${TC_DURATION_IN_SECONDS}
+
+Notifications_rate_20k
+ ${20000} ${TC_DURATION_IN_SECONDS}
+
+Notifications_rate_60k
+ ${60000} ${TC_DURATION_IN_SECONDS}
# Place the suites in run order:
integration/test/csit/suites/controller/OneNode_Datastore/010_crud_mdsal_perf.robot
+integration/test/csit/suites/controller/dom_notification_broker/noloss_rate_1node.robot
-<input>
- <seconds>$SECONDS</seconds>
- <notifications-per-second>$NPS</notifications-per-second>
+<input xmlns="tag:opendaylight.org,2017:controller:yang:lowlevel:control">
+ <id>$ID</id>
+ <seconds>$DURATION</seconds>
+ <notifications-per-second>$RATE</notifications-per-second>
</input>
+
--- /dev/null
+<input xmlns="tag:opendaylight.org,2017:controller:yang:lowlevel:control">
+ <id>$ID</id>
+</input>
+
--- /dev/null
+<input xmlns="tag:opendaylight.org,2017:controller:yang:lowlevel:control">
+ <id>$ID</id>
+</input>
+