Automate SIP Flow testing with Sipper

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&#91;:SessionRecord&#93;='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 = &#91;'< 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.

Advertisements

One thought on “Automate SIP Flow testing with Sipper

  1. We are pleased to see the growing list of Sipper users and that Sipper is helping the VOIP community.

    Sipper has been developed with Test Driven approach so every feature in Sipper has a corresponding test for it in sipper_test directory. It is a very good source for example test cases. You can find the sipper_test under “\ruby\lib\ruby\gems\1.8\gems\Sipper-2.0.0\sipper_test”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s