Test RTP Lua Agent
Introduction
The TestRtpLuaAgent is an asynchronous helper for LUA scripts running within the LogicApp. It is used for performing RTP Testing. This agent exists primarily to support the automated regression testing of the N-Squared family of SIP/RTP products (the N2SIP framework).
The agent supports the ability to automate testing of:
- The receiving and validation of RTP audio stream packets sent from N2SIP.
- The sending of RTP telephony event (key-press event) packets into N2SIP.
The agent does not currently support the ability to send RTP audio stream packets into N2SIP.
The agent does not currently support the ability to send or receive RTCP.
The TestRtpLuaAgent communicates with one or more instances of the TestRtpApp which performs the RTP packet send/receive over UDP.
The TestRtpLuaAgent communicates with the TestRtpApp using the TEST-RTP-… messages.
The TestRtpLuaAgent is tied to the test_rtp
action key.
The N-Squared application with which we exchange the RTP Requests and Responses is the RtpApp, although in theory any external RTP endpoint can be tested using this library.
Configuring TestRtpLuaAgent
The TestRtpLuaAgent is configured within a LogicApp.
<?xml version="1.0" encoding="utf-8"?>
<n2svcd>
...
<applications>
...
<application name="Logic" module="LogicApp">
<include>
<lib>../apps/logic/lib</lib>
</include>
<parameters>
...
<parameter name="default_test_rtp_app_name" value="TestRtpApp"/>
</parameters>
<config>
<services>
...
</services>
<agents>
<agent module="TestRtpApp::TestRtpLuaAgent" libs="../../n2sip/apps/test_rtp/lib"/>
</agents>
</config>
</application>
...
</application>
...
</n2svcd>
Under normal installation, following agent
attributes apply:
Attribute | Type | XML Type | Description |
---|---|---|---|
module
|
TestRtpApp::TestRtpLuaAgent
|
Attribute | [Required] The module name containing the Test RTP Agent code. |
libs
|
../../n2sip/apps/test_rtp/lib
|
Element |
Location of the module for TestRtpLuaAgent.
|
expect_secs
|
Integer | Attribute |
The number of seconds to wait for an inbound message (or no-message). This value is set globally and currently cannot be controlled on a per-request basis. (Default = 10 seconds).
|
In addition, the TestRtpLuaAgent must be configured with the name of the TestRtpApp with which
it will communicate. This is configured within the parameters
of the containing LogicApp
.
Attribute | Type | Description |
---|---|---|
parameters
|
Array |
Array of name = value Parameters for this Application instance.
|
.default_test_rtp_app_name
|
String | Default name for the TestRtpApp to which TestRtpLuaAgent will send test instructions and receive test inputs. |
The TestRtpLuaAgent API
All methods may raise a LUA Error in the case of exception, including:
- Invalid input parameters supplied by LUA script.
- Unexpected results structure returned from TestRtpApp.
- Processing error occurred at TestRtpApp.
- Timeout occurred when waiting for the TestRtpApp response.
Complete Example
A LUA Script can access the TestRtpLuaAgent test_rtp
action with code such as the following.
This example uses the Test SIP Agent to set up a SIP call which establishes an RTP stream, during which digit collection is performed:
local n2svcd = require "n2.n2svcd"
local utils = require "n2.utils"
local match = require "n2.n2svcd.tester.match"
local manage = require "n2.n2svcd.tester.manage"
local edr_file_agent = require "n2.n2svcd.edr_file_agent"
local tsuo = require "n2.n2svcd.tester.test_sip_agent"
local truo = require "n2.n2svcd.tester.test_rtp_agent"
local args = ...
-- Register our local RTP port.
local result = truo.register ()
local rtp_listener_port = result.local_port
-- Basic call parameters.
local endpoints = tsuo.default_endpoints ({ local_rtp_port = rtp_listener_port })
local calling_party = '665566'
local called_party = '8000'
local context = tsuo.invite_context (endpoints, calling_party, called_party)
local sdp_offer = tsuo.sdp_offer (context, tsuo.SDP_MEDIA_LINPHONE)
-- INVITE.
local tv = match.elapsed ()
tsuo.invite_send_request (context, sdp_offer, { { name = 'Scenario', value = '801' } })
tsuo.invite_expect_response (context, 100, "Trying")
-- 200 OK.
local response = tsuo.invite_expect_response (context, 200, "OK", nil, { sdp_media = tsuo.SDP_MEDIA_LINPHONE_U })
tv = match.elapsed ("Call Answered (immediate)", tv, 0)
tsuo.invite_send_2xx_ack (context)
-- Request our RTP tester to connect to the far-end IP/port. Now we can send RTP as well as receive it.
truo.connect (response.sdp.connection.ip4.address, response.sdp.media.audio.port)
-- The prompt is 3.6s long. We start entering digits (telephone-event ID 102) after 2 seconds.
n2svcd.wait (2.0)
-- This should interrupt the announcement and start the spooling of silence until we're finished.
truo.send_telephone_event (102, truo.DIGIT_CODES['1'], 200)
n2svcd.wait (0.4)
truo.send_telephone_event (102, truo.DIGIT_CODES['2'], 210)
n2svcd.wait (0.4)
truo.send_telephone_event (102, truo.DIGIT_CODES['3'], 190)
n2svcd.wait (0.4)
truo.send_telephone_event (102, truo.DIGIT_CODES['4'], 990)
-- That last digit will take 1 second to complete.
-- Then we get the variable part announcement.
-- Then we get the goodbye announcement.
tsuo.bye_expect_request (context)
tv = match.elapsed ("PACUI Script Ends (8.35s)", tv, 8.35, 8.55)
-- Construct and Send ACK Request suitable for the 200 response we received.
-- The LHO is now in PLAYING state (waiting for the ARI).
tsuo.bye_send_response (context, 200, "OK")
-- Define list of expected announcements and silence we expect in our buffer.
local expected_rtp_config = {
encoding = 'PCMU/8000',
fragments = {
{ files = { 'English/announcements/Enter_Amount.ul' }, min = 2.15, max = 2.3 },
{ silence_min = 1.94, silence_max = 2.1 },
{ files = {
'English/announcements/You_Entered.ul',
'English/variable_parts/1.ul',
'English/variable_parts/2.ul',
'English/variable_parts/3.ul',
'English/variable_parts/4.ul',
}
},
{ silence_min = 0, silence_max = 0.1 },
{ files = { 'English/announcements/Goodbye.ul' } },
{ silence_min = 0, silence_max = 0.1 },
}
}
-- Trigger a collection of RTP packets and match against the expected configuration.
truo.fetch_and_match (expected_rtp_config);
Endpoint Setup
At the start of each stream, we must negotiate with the Test RTP Agent to specify the UDP port numbers and IP addresses that will be used in each direction.
Refer to the RTP Endpoint Setup methods.
Stream Sending
The test library supports the ability to send telephone-event RTP packets, and to send AMR wideband stream attribute change packets. It is not currently possible to send audio data to the remote endpoint using this library.
Refer to the RTP Send methods.
Stream Matching
Audio stream packets sent to the tester by the remote endpoint are cached in a buffer until such time as the tester may be ready to validate them. The test library provides a method which will retrieve all of the received/cached audio packets and validate them against an expected audio stream.
Refer to the RTP Stream Matching methods.