If you are into VOIP development and want to automate your sip call flows for testing, you might be interested in this project SIPr.
I have been involved in a project for a few months now which provides an advanced callcenter service leveraging the Broadworks Platform. Like any callcenter, the customer calls the CallCenter , Callcenter Queues the Call and Selects an agent and delivers the Call to the Agent. The agent is a registered user of Broadworks.
I have been looking for the right tool to automate the SIP Call Flows. After playing a while with sippr, I end up writing these test cases:
The CUSTOMER controller:
It justs sends the INVITE to a broadworks number which is the QUEUE. After the call gets received, it waits and sends BYE to terminate the call.
require 'sip_test_driver_controller'
class CustomerController < SIP::SipTestDriverController
transaction_usage :use_transactions=>false
start_on_load false
def initialize
logd('Controller created')
end
def on_provisional_res(session)
end
def start
session = create_udp_session(SipperConfigurator[:DefaultRIP], SipperConfigurator[:DefaultRP])
session.request_with('INVITE', 'sip:sajidqueue1@bwas.broadworkslab.com')
puts 'Sending INVITE Dest: ', 'sip:sajidqueue1@bwas.broadworkslab.com';
end
def on_invite(session)
puts 'customer got re-invite : '
session.respond_with(200)
session.schedule_timer_for("send 200!", 15000)
end
def on_timer(session , task)
puts 'sending bye'
session.request_with('BYE')
session.invalidate(true)
end
def on_success_res(session)
puts 'customer ---> on_success_res'
session.request_with('ACK')
end
end
Here is the Agent Controller:
It registers with Broadworks and waits for calls from the queue and receives it after 10 sec Ring and then waits for the BYE from the customer.
require 'sip_test_driver_controller'
class AgentController < SIP::SipTestDriverController
transaction_usage :use_transactions=>false
# change the directive below to true to start after loading.
start_on_load false
def specified_transport
[SipperConfigurator[:LocalSipperIP],SipperConfigurator[:LocalSipperPort][1]]
end
def initialize
logd('Controller created')
end
def on_invite(session)
if !session['invite']
puts 'Agent got call from Queue '
session.respond_with(100)
session.respond_with(180)
session['invite']=1
session.schedule_timer_for("send 200!", 5000)
else
puts 'agent got re-invite'
session.respond_with(200)
end
end
def on_timer(session , task)
puts 'Agent is going to accept the call from customer!', task
session.respond_with(200)
end
def on_bye(session)
puts 'Agent received BYE from Customer!'
session.respond_with(200)
session.invalidate(true)
session.flow_completed_for("CustomerAgentTest")
end
def on_provisional_res(session)
end
def start
contact = SipperConfigurator[:LocalSipperIP]+":"
r = Request.create_initial("REGISTER", "sip:" + "bwas.broadworkslab.com'",
:from=>"sip:2401120075@bwas.dhaka.vantage.com", :to=>"sip:2401120075@bwas.broadworkslab.com'",
:contact=>"sip:sajidagent1@"+ SipperConfigurator[:LocalSipperIP]+":"+SipperConfigurator[:LocalSipperPort][1].to_s(),
:expires=>"300",
:cseq=>"1 REGISTER",
:p_session_record=>"msg-info")
r.contact.q="0.9"
session = create_udp_session(SipperConfigurator[:DefaultRIP], SipperConfigurator[:DefaultRP])
#session.create_register_request('sip:bwas.dhaka.vantage.com', '<sip:sajidagent1@bwas.broadworkslab.com'>')
session.send(r)
#print "Sent a new REGISTER from "+name+"\n"
end
def on_success_res_for_register(s)
s.invalidate(true);
end
def on_success_res(session)
puts 'on_success_res->'
end
def on_ack(session)
end
def on_failure_res(session)
if session.iresponse.code == 401
r = session.create_request_with_response_to_challenge(session.iresponse.www_authenticate, false,"a", "b")
session.send r
session[:auth] = r.authorization
end
end
end
And Here is the Test Case that runs both controller and performs Validation/Assertion for the call flow.
$:.unshift File.join(ENV['SIPPER_HOME'],'sipper_test')
require 'driven_sip_test_case'
class CustomerAgentTest < DrivenSipTestCase
def setup
super
SipperConfigurator[:SessionRecord]='msg-info'
puts '------------------------------------'
end
def test_case1
start_named_controller_non_blocking("AgentController")
sleep 1
start_named_controller_non_blocking("CustomerController")
#it waits for Agent & Customer flow complete. The agent controller triggers the completion with session.flow_completed_for invocation.
wait_for_signaling()
self.expected_flow = ['< INVITE', '> 100', '> 180', '> 200', '< ACK ' , '< INVITE', '> 200', '< ACK', '< INVITE', '> 200', '< ACK' , '< BYE', '> 200']
verify_call_flow(:in,0)
self.expected_flow = ['> INVITE', '< 100 {0,}', '< 200', '> ACK', '< INVITE', '> 200', '< ACK', '< INVITE', '> 200', '< ACK', '> BYE' ]
verify_call_flow(:out, 1)
puts "done tests"
end
end
Ain’t this cool! Just a few lines of Code and you get a test case with Both UAC & UAS simulation!. I wish the Sipper Guys posted some more examples. We are planning to integrate this testcases with Watir & FunFX to automate the Full VOICE + WEB Mash up.