mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
#9621: Implement conference functional tests
This commit is contained in:
@ -59,11 +59,15 @@ class SflPhoneCtrl(Thread):
|
|||||||
onCallCurrent_cb
|
onCallCurrent_cb
|
||||||
onCallBusy_cb
|
onCallBusy_cb
|
||||||
onCallFailure_cb
|
onCallFailure_cb
|
||||||
|
onConferenceCreated_cb
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# list of active calls (known by the client)
|
# list of active calls (known by the client)
|
||||||
activeCalls = {}
|
activeCalls = {}
|
||||||
|
|
||||||
|
# list of active conferences
|
||||||
|
activeConferences = {}
|
||||||
|
|
||||||
def __init__(self, name=sys.argv[0]):
|
def __init__(self, name=sys.argv[0]):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
|
||||||
@ -74,6 +78,7 @@ class SflPhoneCtrl(Thread):
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
self.currentCallId = ""
|
self.currentCallId = ""
|
||||||
|
self.currentConfId = ""
|
||||||
|
|
||||||
self.isStop = False
|
self.isStop = False
|
||||||
|
|
||||||
@ -145,6 +150,7 @@ class SflPhoneCtrl(Thread):
|
|||||||
print "Adding Incoming call method"
|
print "Adding Incoming call method"
|
||||||
proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall)
|
proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall)
|
||||||
proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged)
|
proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged)
|
||||||
|
proxy_callmgr.connect_to_signal('conferenceCreated', self.onConferenceCreated)
|
||||||
except dbus.DBusException, e:
|
except dbus.DBusException, e:
|
||||||
print e
|
print e
|
||||||
|
|
||||||
@ -171,7 +177,7 @@ class SflPhoneCtrl(Thread):
|
|||||||
def onIncomingCall_cb(self):
|
def onIncomingCall_cb(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def onCallHangup_cb(self):
|
def onCallHangup_cb(self, callId):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def onCallRinging_cb(self):
|
def onCallRinging_cb(self):
|
||||||
@ -202,7 +208,7 @@ class SflPhoneCtrl(Thread):
|
|||||||
def onCallHangUp(self, callid):
|
def onCallHangUp(self, callid):
|
||||||
""" Remove callid from call list """
|
""" Remove callid from call list """
|
||||||
|
|
||||||
self.onCallHangup_cb()
|
self.onCallHangup_cb(callid)
|
||||||
self.currentCallId = ""
|
self.currentCallId = ""
|
||||||
del self.activeCalls[callid]
|
del self.activeCalls[callid]
|
||||||
|
|
||||||
@ -274,6 +280,12 @@ class SflPhoneCtrl(Thread):
|
|||||||
else:
|
else:
|
||||||
print "unknown state"
|
print "unknown state"
|
||||||
|
|
||||||
|
def onConferenceCreated_cb(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def onConferenceCreated(self, confId):
|
||||||
|
self.currentConfId = confId
|
||||||
|
self.onConferenceCreated_cb()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Account management
|
# Account management
|
||||||
@ -545,9 +557,6 @@ class SflPhoneCtrl(Thread):
|
|||||||
for call in self.activeCalls:
|
for call in self.activeCalls:
|
||||||
print "\t" + call
|
print "\t" + call
|
||||||
|
|
||||||
#
|
|
||||||
# Action
|
|
||||||
#
|
|
||||||
def Call(self, dest):
|
def Call(self, dest):
|
||||||
"""Start a call and return a CallID
|
"""Start a call and return a CallID
|
||||||
|
|
||||||
@ -636,12 +645,6 @@ class SflPhoneCtrl(Thread):
|
|||||||
def Hold(self, callid):
|
def Hold(self, callid):
|
||||||
"""Hold a call identified by a CallID"""
|
"""Hold a call identified by a CallID"""
|
||||||
|
|
||||||
# if not self.account:
|
|
||||||
# self.setFirstRegisteredAccount()
|
|
||||||
|
|
||||||
# if not self.isAccountRegistered():
|
|
||||||
# raise SflPhoneError("Can't hold a call without a registered account")
|
|
||||||
|
|
||||||
if callid is None or callid == "":
|
if callid is None or callid == "":
|
||||||
raise SflPhoneError("Invalid callID")
|
raise SflPhoneError("Invalid callID")
|
||||||
|
|
||||||
@ -651,12 +654,6 @@ class SflPhoneCtrl(Thread):
|
|||||||
def UnHold(self, callid):
|
def UnHold(self, callid):
|
||||||
"""Unhold an incoming call identified by a CallID"""
|
"""Unhold an incoming call identified by a CallID"""
|
||||||
|
|
||||||
# if not self.account:
|
|
||||||
# self.setFirstRegisteredAccount()
|
|
||||||
|
|
||||||
# if not self.isAccountRegistered():
|
|
||||||
# raise SflPhoneError("Can't unhold a call without a registered account")
|
|
||||||
|
|
||||||
if callid is None or callid == "":
|
if callid is None or callid == "":
|
||||||
raise SflPhoneError("Invalid callID")
|
raise SflPhoneError("Invalid callID")
|
||||||
|
|
||||||
@ -679,13 +676,30 @@ class SflPhoneCtrl(Thread):
|
|||||||
callid = m.hexdigest()
|
callid = m.hexdigest()
|
||||||
return callid
|
return callid
|
||||||
|
|
||||||
|
|
||||||
|
def createConference(self, call1Id, call2Id):
|
||||||
|
""" Create a conference given the two call ids """
|
||||||
|
|
||||||
|
self.callmanager.joinParticipant(call1Id, call2Id)
|
||||||
|
|
||||||
|
|
||||||
|
def hangupConference(self, confId):
|
||||||
|
""" Hang up each call for this conference """
|
||||||
|
|
||||||
|
self.callmanager.hangUpConference(confId)
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Processing method for this thread"""
|
"""Processing method for this thread"""
|
||||||
|
|
||||||
context = self.loop.get_context()
|
context = self.loop.get_context()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
context.iteration(True)
|
context.iteration(True)
|
||||||
|
|
||||||
if self.isStop:
|
if self.isStop:
|
||||||
|
print "++++++++++++++++++++++++++++++++++++++++"
|
||||||
|
print "++++++++++++++++++++++++++++++++++++++++"
|
||||||
|
print "++++++++++++++++++++++++++++++++++++++++"
|
||||||
|
print "++++++++++++++++++++++++++++++++++++++++"
|
||||||
return
|
return
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
#
|
#
|
||||||
# Copyright (C) 2009 by the Free Software Foundation, Inc.
|
# Copyright (C) 2012 by the Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -22,7 +24,7 @@ class SippWrapper:
|
|||||||
""" Wrapper taht allow for managing sipp command line easily """
|
""" Wrapper taht allow for managing sipp command line easily """
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.commandLine = "sipp"
|
self.commandLine = "./sipp"
|
||||||
self.remoteServer = ""
|
self.remoteServer = ""
|
||||||
self.remotePort = ""
|
self.remotePort = ""
|
||||||
self.localInterface = ""
|
self.localInterface = ""
|
||||||
@ -41,9 +43,11 @@ class SippWrapper:
|
|||||||
self.enableTraceRtt = False
|
self.enableTraceRtt = False
|
||||||
self.enableTraceLogs = False
|
self.enableTraceLogs = False
|
||||||
|
|
||||||
def buildCommandLine(self):
|
def buildCommandLine(self, port):
|
||||||
""" Fill the command line arguments based on specified parameters """
|
""" Fill the command line arguments based on specified parameters """
|
||||||
|
|
||||||
|
self.localPort = str(port)
|
||||||
|
|
||||||
if not self.remotePort and not self.remoteServer:
|
if not self.remotePort and not self.remoteServer:
|
||||||
self.isUserAgentClient = False
|
self.isUserAgentClient = False
|
||||||
elif self.remotePort and not self.remoteServer:
|
elif self.remotePort and not self.remoteServer:
|
||||||
@ -106,9 +110,8 @@ class SippWrapper:
|
|||||||
def launch(self):
|
def launch(self):
|
||||||
""" Launch the sipp instance using the specified arguments """
|
""" Launch the sipp instance using the specified arguments """
|
||||||
|
|
||||||
self.buildCommandLine()
|
|
||||||
print self.commandLine
|
print self.commandLine
|
||||||
return os.system(self.commandLine)
|
return os.system(self.commandLine + " 2>&1 > /dev/null")
|
||||||
|
|
||||||
|
|
||||||
class SippScreenStatParser:
|
class SippScreenStatParser:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env python
|
#!/USR/BIN/ENV PYTHON
|
||||||
#
|
#
|
||||||
# Copyright (C) 2009 by the Free Software Foundation, Inc.
|
# Copyright (C) 2012 by the Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or
|
# This program is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU General Public License
|
# modify it under the terms of the GNU General Public License
|
||||||
@ -18,7 +20,9 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import yaml
|
||||||
import logging
|
import logging
|
||||||
|
import multiprocessing
|
||||||
from sippwrap import SippWrapper
|
from sippwrap import SippWrapper
|
||||||
from sippwrap import SippScreenStatParser
|
from sippwrap import SippScreenStatParser
|
||||||
from sflphonectrl import SflPhoneCtrl
|
from sflphonectrl import SflPhoneCtrl
|
||||||
@ -29,10 +33,62 @@ from nose.tools import nottest
|
|||||||
### function starting with 'test' are executed.
|
### function starting with 'test' are executed.
|
||||||
###
|
###
|
||||||
|
|
||||||
accountList = ["IP2IP", "Account:1332798167"]
|
|
||||||
|
|
||||||
SCENARIO_PATH = "../sippxml/"
|
SCENARIO_PATH = "../sippxml/"
|
||||||
|
|
||||||
|
class SippCtrl:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.remoteServer = "127.0.0.1"
|
||||||
|
self.remotePort = str(5062)
|
||||||
|
self.localInterface = "127.0.0.1"
|
||||||
|
self.localPort = str(5060)
|
||||||
|
|
||||||
|
def initialize_sipp_registration_instance(self, instance, xmlScenario):
|
||||||
|
instance.remoteServer = self.remoteServer
|
||||||
|
instance.remotePort = self.remotePort
|
||||||
|
instance.localInterface = self.localInterface
|
||||||
|
instance.localPort = self.localPort
|
||||||
|
instance.customScenarioFile = SCENARIO_PATH + xmlScenario
|
||||||
|
instance.numberOfCall = 1
|
||||||
|
instance.numberOfSimultaneousCall = 1
|
||||||
|
|
||||||
|
def initialize_sipp_call_instance(self, instance):
|
||||||
|
instance.localInterface = self.localInterface
|
||||||
|
instance.localPort = self.localPort
|
||||||
|
instance.numberOfCall = 1
|
||||||
|
instance.numberOfSimultaneousCall = 1
|
||||||
|
instance.enableTraceScreen = True
|
||||||
|
|
||||||
|
def launchSippProcess(self, sippInstance, localPort):
|
||||||
|
sippInstance.buildCommandLine(localPort)
|
||||||
|
sippInstance.launch()
|
||||||
|
|
||||||
|
def find_sipp_pid(self):
|
||||||
|
# Retreive the PID of the last
|
||||||
|
# The /proc/PID/cmdline contain the command line from
|
||||||
|
pids = [int(x) for x in os.listdir("/proc") if x.isdigit()]
|
||||||
|
sippPid = [pid for pid in pids if "sipp" in open("/proc/" + str(pid) + "/cmdline").readline()]
|
||||||
|
|
||||||
|
return sippPid[0]
|
||||||
|
|
||||||
|
def clean_log_directory(self):
|
||||||
|
dirlist = os.listdir("./")
|
||||||
|
files = [x for x in dirlist if "screen.log" in x]
|
||||||
|
for f in files:
|
||||||
|
os.remove(f)
|
||||||
|
|
||||||
|
def parse_results(self):
|
||||||
|
dirlist = os.listdir("./")
|
||||||
|
logfile = [x for x in dirlist if "screen.log" in x]
|
||||||
|
|
||||||
|
fullpath = os.path.dirname(os.path.realpath(__file__)) + "/"
|
||||||
|
|
||||||
|
# there should be only one screen.log file (see clean_log_directory)
|
||||||
|
resultParser = SippScreenStatParser(fullpath + logfile[0])
|
||||||
|
|
||||||
|
assert(not resultParser.isAnyFailedCall())
|
||||||
|
assert(resultParser.isAnySuccessfulCall())
|
||||||
|
|
||||||
class TestSFLPhoneAccountConfig(SflPhoneCtrl):
|
class TestSFLPhoneAccountConfig(SflPhoneCtrl):
|
||||||
""" The test suite for account configuration """
|
""" The test suite for account configuration """
|
||||||
|
|
||||||
@ -46,14 +102,40 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
|
|||||||
self.logger.addHandler(filehdlr)
|
self.logger.addHandler(filehdlr)
|
||||||
self.logger.setLevel(logging.INFO)
|
self.logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
@nottest
|
|
||||||
|
def get_config(self):
|
||||||
|
""" Parsse configuration file and return a dictionary """
|
||||||
|
config = {}
|
||||||
|
with open("sflphoned.functest.yml","r") as stream:
|
||||||
|
config = yaml.load(stream)
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def get_account_list_from_config(self):
|
||||||
|
""" Get the accout list from config and add IP2IP """
|
||||||
|
|
||||||
|
config = self.get_config()
|
||||||
|
|
||||||
|
accounts = config["preferences"]["order"]
|
||||||
|
accountList = accounts.split('/')
|
||||||
|
del accountList[len(accountList)-1]
|
||||||
|
accountList.append("IP2IP")
|
||||||
|
|
||||||
|
return accountList
|
||||||
|
|
||||||
|
|
||||||
def test_get_account_list(self):
|
def test_get_account_list(self):
|
||||||
self.logger.info("Test get account list")
|
self.logger.info("Test get account list")
|
||||||
|
|
||||||
|
accountList = self.get_account_list_from_config()
|
||||||
|
|
||||||
|
# make sure that the intersection between the list is of same size
|
||||||
accList = self.getAllAccounts()
|
accList = self.getAllAccounts()
|
||||||
listIntersection = set(accList) & set(accountList)
|
listIntersection = set(accList) & set(accountList)
|
||||||
assert len(listIntersection) == len(accountList)
|
assert len(listIntersection) == len(accountList)
|
||||||
|
|
||||||
@nottest
|
|
||||||
def test_account_registration(self):
|
def test_account_registration(self):
|
||||||
self.logger.info("Test account registration")
|
self.logger.info("Test account registration")
|
||||||
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
||||||
@ -72,6 +154,24 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
|
|||||||
|
|
||||||
assert self.isAccountRegistered(acc)
|
assert self.isAccountRegistered(acc)
|
||||||
|
|
||||||
|
|
||||||
|
@nottest
|
||||||
|
def test_get_account_details(self):
|
||||||
|
self.logger.info("Test account details")
|
||||||
|
|
||||||
|
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
||||||
|
|
||||||
|
config = self.get_config()
|
||||||
|
|
||||||
|
accountDetails = {}
|
||||||
|
for acc in accList:
|
||||||
|
accountDetails[acc] = self.getAccountDetails(acc)
|
||||||
|
|
||||||
|
accountConfDetails = {}
|
||||||
|
for accConf in config["accounts"]:
|
||||||
|
accountConfDetails[accConf["id"]] = accConf
|
||||||
|
|
||||||
|
|
||||||
@nottest
|
@nottest
|
||||||
def test_add_remove_account(self):
|
def test_add_remove_account(self):
|
||||||
self.logger.info("Test add/remove account")
|
self.logger.info("Test add/remove account")
|
||||||
@ -99,11 +199,12 @@ class TestSFLPhoneAccountConfig(SflPhoneCtrl):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
|
class TestSFLPhoneRegisteredCalls(SflPhoneCtrl, SippCtrl):
|
||||||
""" The test suite for call interaction """
|
""" The test suite for call interaction """
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
SflPhoneCtrl.__init__(self)
|
SflPhoneCtrl.__init__(self)
|
||||||
|
SippCtrl.__init__(self)
|
||||||
|
|
||||||
self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls")
|
self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls")
|
||||||
filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log")
|
filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log")
|
||||||
@ -113,8 +214,6 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
|
|||||||
self.logger.setLevel(logging.INFO)
|
self.logger.setLevel(logging.INFO)
|
||||||
self.sippRegistrationInstance = SippWrapper()
|
self.sippRegistrationInstance = SippWrapper()
|
||||||
self.sippCallInstance = SippWrapper()
|
self.sippCallInstance = SippWrapper()
|
||||||
self.localInterface = "127.0.0.1"
|
|
||||||
self.localPort = str(5064)
|
|
||||||
|
|
||||||
# Make sure the test directory is populated with most recent log files
|
# Make sure the test directory is populated with most recent log files
|
||||||
self.clean_log_directory()
|
self.clean_log_directory()
|
||||||
@ -143,70 +242,26 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
|
|||||||
self.stopThread()
|
self.stopThread()
|
||||||
|
|
||||||
|
|
||||||
def clean_log_directory(self):
|
|
||||||
dirlist = os.listdir("./")
|
|
||||||
files = [x for x in dirlist if "screen.log" in x]
|
|
||||||
for f in files:
|
|
||||||
os.remove(f)
|
|
||||||
|
|
||||||
|
|
||||||
def find_sipp_pid(self):
|
|
||||||
# Retreive the PID of the last
|
|
||||||
# The /proc/PID/cmdline contain the command line from
|
|
||||||
pids = [int(x) for x in os.listdir("/proc") if x.isdigit()]
|
|
||||||
sippPid = [pid for pid in pids if "sipp" in open("/proc/" + str(pid) + "/cmdline").readline()]
|
|
||||||
|
|
||||||
return sippPid[0]
|
|
||||||
|
|
||||||
|
|
||||||
def parse_results(self):
|
|
||||||
dirlist = os.listdir("./")
|
|
||||||
logfile = [x for x in dirlist if "screen.log" in x]
|
|
||||||
print logfile
|
|
||||||
|
|
||||||
fullpath = os.path.dirname(os.path.realpath(__file__)) + "/"
|
|
||||||
|
|
||||||
# there should be only one screen.log file (see clean_log_directory)
|
|
||||||
resultParser = SippScreenStatParser(fullpath + logfile[0])
|
|
||||||
|
|
||||||
assert(not resultParser.isAnyFailedCall())
|
|
||||||
assert(resultParser.isAnySuccessfulCall())
|
|
||||||
|
|
||||||
|
|
||||||
def test_registered_call(self):
|
def test_registered_call(self):
|
||||||
self.logger.info("Test Registered Call")
|
self.logger.info("Test Registered Call")
|
||||||
|
|
||||||
# launch the sipp instance in background
|
# Launch a sipp instance for account registration on asterisk
|
||||||
# sipp 127.0.0.1:5060 -sf uac_register_no_cvs.xml -i 127.0.0.1 -p 5062
|
# this account will then be used to receive call from sflphone
|
||||||
self.sippRegistrationInstance.remoteServer = "127.0.0.1"
|
self.initialize_sipp_registration_instance(self.sippRegistrationInstance, "uac_register_no_cvs_300.xml")
|
||||||
self.sippRegistrationInstance.remotePort = str(5062)
|
regd = multiprocessing.Process(name='sipp1register', target=self.launchSippProcess,
|
||||||
self.sippRegistrationInstance.localInterface = self.localInterface
|
args=(self.sippRegistrationInstance, 5064,))
|
||||||
self.sippRegistrationInstance.localPort = self.localPort
|
regd.start()
|
||||||
self.sippRegistrationInstance.customScenarioFile = SCENARIO_PATH + "uac_register_no_cvs.xml"
|
|
||||||
self.sippRegistrationInstance.launchInBackground = True
|
|
||||||
self.sippRegistrationInstance.numberOfCall = 1
|
|
||||||
self.sippRegistrationInstance.numberOfSimultaneousCall = 1
|
|
||||||
|
|
||||||
self.sippRegistrationInstance.launch()
|
# wait for the registration to complete
|
||||||
|
regd.join()
|
||||||
|
|
||||||
# wait for this instance of sipp to complete registration
|
# Launch a sipp instance waiting for a call from previously registered account
|
||||||
sippPid = self.find_sipp_pid()
|
self.initialize_sipp_call_instance(self.sippCallInstance)
|
||||||
while os.path.exists("/proc/" + str(sippPid)):
|
calld = multiprocessing.Process(name='sipp1call', target=self.launchSippProcess,
|
||||||
time.sleep(1)
|
args=(self.sippCallInstance, 5064,))
|
||||||
|
calld.start()
|
||||||
|
|
||||||
# sipp -sn uas -p 5062 -i 127.0.0.1
|
# Make sure every account are enabled
|
||||||
self.sippCallInstance.localInterface = self.localInterface
|
|
||||||
self.sippCallInstance.localPort = self.localPort
|
|
||||||
self.sippCallInstance.launchInBackground = True
|
|
||||||
self.sippCallInstance.numberOfCall = 1
|
|
||||||
self.sippCallInstance.numberOfSimultaneousCall = 1
|
|
||||||
self.sippCallInstance.enableTraceScreen = True
|
|
||||||
|
|
||||||
self.sippCallInstance.launch()
|
|
||||||
|
|
||||||
sippPid = self.find_sipp_pid()
|
|
||||||
|
|
||||||
# make sure every account are enabled
|
|
||||||
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
||||||
for acc in accList:
|
for acc in accList:
|
||||||
if not self.isAccountRegistered(acc):
|
if not self.isAccountRegistered(acc):
|
||||||
@ -215,11 +270,143 @@ class TestSFLPhoneRegisteredCalls(SflPhoneCtrl):
|
|||||||
# Make a call to the SIPP instance
|
# Make a call to the SIPP instance
|
||||||
self.Call("300")
|
self.Call("300")
|
||||||
|
|
||||||
# Start Glib mainloop to process callbacks
|
# Start the threaded loop to handle GLIB cllbacks
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
# Wait the sipp instance to dump log files
|
# Wait for the sipp instance to dump log files
|
||||||
while os.path.exists("/proc/" + str(sippPid)):
|
calld.join()
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
self.stopThread()
|
||||||
self.parse_results()
|
self.parse_results()
|
||||||
|
|
||||||
|
|
||||||
|
class TestSFLPhoneConferenceCalls(SflPhoneCtrl, SippCtrl):
|
||||||
|
""" Test Conference calls """
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
SflPhoneCtrl.__init__(self)
|
||||||
|
SippCtrl.__init__(self)
|
||||||
|
|
||||||
|
self.logger = logging.getLogger("TestSFLPhoneRegisteredCalls")
|
||||||
|
filehdlr = logging.FileHandler("/tmp/sfltestregisteredcall.log")
|
||||||
|
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
|
||||||
|
filehdlr.setFormatter(formatter)
|
||||||
|
self.logger.addHandler(filehdlr)
|
||||||
|
self.logger.setLevel(logging.INFO)
|
||||||
|
self.sippRegistrationInstanceA = SippWrapper()
|
||||||
|
self.sippRegistrationInstanceB = SippWrapper()
|
||||||
|
self.sippCallInstanceA = SippWrapper()
|
||||||
|
self.sippCallInstanceB = SippWrapper()
|
||||||
|
self.localPortCallA = str(5064)
|
||||||
|
self.localPortCallB = str(5066)
|
||||||
|
self.callCount = 0
|
||||||
|
self.accountCalls = []
|
||||||
|
|
||||||
|
# Make sure the test directory is populated with most recent log files
|
||||||
|
# self.clean_log_directory()
|
||||||
|
|
||||||
|
|
||||||
|
def onCallCurrent_cb(self):
|
||||||
|
""" On incoming call, answer the call, then hangup """
|
||||||
|
|
||||||
|
self.callCount += 1
|
||||||
|
|
||||||
|
self.accountCalls.append(self.currentCallId)
|
||||||
|
print "Account List: ", str(self.accountCalls)
|
||||||
|
|
||||||
|
if self.callCount == 2:
|
||||||
|
self.createConference(self.accountCalls[0], self.accountCalls[1])
|
||||||
|
|
||||||
|
|
||||||
|
def onCallRinging_cb(self):
|
||||||
|
""" Display messages when call is ringing """
|
||||||
|
|
||||||
|
print "The call is ringing"
|
||||||
|
|
||||||
|
|
||||||
|
def onCallHangup_cb(self, callId):
|
||||||
|
""" Exit thread when all call are finished """
|
||||||
|
|
||||||
|
if callId in self.accountCalls:
|
||||||
|
self.accountCalls.remove(callId)
|
||||||
|
|
||||||
|
self.callCount -= 1
|
||||||
|
if self.callCount == 0:
|
||||||
|
self.stopThread()
|
||||||
|
|
||||||
|
|
||||||
|
def onCallFailure_cb(self):
|
||||||
|
""" If a failure occurs duing the call, just leave the running thread """
|
||||||
|
|
||||||
|
print "Stopping Thread"
|
||||||
|
self.stopThread()
|
||||||
|
|
||||||
|
|
||||||
|
def onConferenceCreated_cb(self):
|
||||||
|
""" Called once the conference is created """
|
||||||
|
|
||||||
|
print "Conference Created ", self.currentConfId
|
||||||
|
print "Conference Hangup ", self.currentConfId
|
||||||
|
|
||||||
|
self.hangupConference(self.currentConfId)
|
||||||
|
|
||||||
|
|
||||||
|
def test_conference_call(self):
|
||||||
|
self.logger.info("Test Registered Call")
|
||||||
|
|
||||||
|
# launch the sipp instance to register the first participant to astersik
|
||||||
|
self.initialize_sipp_registration_instance(self.sippRegistrationInstanceA, "uac_register_no_cvs_300.xml")
|
||||||
|
regd = multiprocessing.Process(name='sipp1register', target=self.launchSippProcess,
|
||||||
|
args=(self.sippRegistrationInstanceA, 5064,))
|
||||||
|
regd.start()
|
||||||
|
regd.join()
|
||||||
|
|
||||||
|
# launch the sipp instance to register the second participant to asterisk
|
||||||
|
self.initialize_sipp_registration_instance(self.sippRegistrationInstanceB, "uac_register_no_cvs_400.xml")
|
||||||
|
regd = multiprocessing.Process(name='sipp2register', target=self.launchSippProcess,
|
||||||
|
args=(self.sippRegistrationInstanceB, 5066,))
|
||||||
|
regd.start()
|
||||||
|
regd.join()
|
||||||
|
|
||||||
|
# launch the sipp instance waining for call as the first participant
|
||||||
|
self.initialize_sipp_call_instance(self.sippCallInstanceA)
|
||||||
|
calldA = multiprocessing.Process(name='sipp1call', target=self.launchSippProcess,
|
||||||
|
args=(self.sippCallInstanceA, 5064,))
|
||||||
|
calldA.start()
|
||||||
|
|
||||||
|
|
||||||
|
# launch the sipp instance waiting for call as the second particpant
|
||||||
|
self.initialize_sipp_call_instance(self.sippCallInstanceB)
|
||||||
|
calldB = multiprocessing.Process(name='sipp2call', target=self.launchSippProcess,
|
||||||
|
args=(self.sippCallInstanceB, 5066,))
|
||||||
|
calldB.start()
|
||||||
|
|
||||||
|
# make sure every account are enabled
|
||||||
|
accList = [x for x in self.getAllAccounts() if x != "IP2IP"]
|
||||||
|
for acc in accList:
|
||||||
|
if not self.isAccountRegistered(acc):
|
||||||
|
self.setAccountEnable(acc, True)
|
||||||
|
|
||||||
|
# make a call to the SIPP instance
|
||||||
|
self.Call("300")
|
||||||
|
self.Call("400")
|
||||||
|
|
||||||
|
# start the main loop for processing glib callbacks
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
print "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
|
||||||
|
calldA.join()
|
||||||
|
print "+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+"
|
||||||
|
calldB.join()
|
||||||
|
|
||||||
|
print "====================================================="
|
||||||
|
|
||||||
|
self.stopThread()
|
||||||
|
self.parse_results()
|
||||||
|
|
||||||
|
|
||||||
|
# callInstance = TestSFLPhoneRegisteredCalls()
|
||||||
|
# callInstance.test_registered_call()
|
||||||
|
|
||||||
|
confInstance = TestSFLPhoneConferenceCalls()
|
||||||
|
confInstance.test_conference_call()
|
||||||
|
110
tools/sippxml/uac_register_no_cvs_400.xml
Normal file
110
tools/sippxml/uac_register_no_cvs_400.xml
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?xml version="1.0" encoding="ISO-8859-2" ?>
|
||||||
|
|
||||||
|
<!-- Use with CSV file struct like: 3000;192.168.1.106;[authentication username=3000 password=3000];
|
||||||
|
(user part of uri, server address, auth tag in each line)
|
||||||
|
-->
|
||||||
|
|
||||||
|
<scenario name="register_client">
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
REGISTER sip:127.0.0.1 SIP/2.0
|
||||||
|
Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
|
||||||
|
From: <sip:300@127.0.0.1>;tag=[call_number]
|
||||||
|
To: <sip:400@127.0.0.1>
|
||||||
|
Call-ID: [call_id]
|
||||||
|
CSeq: [cseq] REGISTER
|
||||||
|
Contact: sip:300@[local_ip]:[local_port]
|
||||||
|
Max-Forwards: 10
|
||||||
|
Expires: 120
|
||||||
|
User-Agent: SIPp/Win32
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<!-- asterisk -->
|
||||||
|
<recv response="200">
|
||||||
|
<!--
|
||||||
|
<action>
|
||||||
|
<ereg regexp=".*" search_in="hdr" header="Contact:" check_it="true" assign_to="1" />
|
||||||
|
</action>
|
||||||
|
-->
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<recv request="INVITE" crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 180 Ringing
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:];tag=[pid]SIPpTag01[call_number]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<send retrans="500">
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 200 OK
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:];tag=[pid]SIPpTag01[call_number]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
|
||||||
|
Content-Type: application/sdp
|
||||||
|
Content-Length: [len]
|
||||||
|
|
||||||
|
v=0
|
||||||
|
o=user1 53655765 2353687637 IN IP[local_ip_type] [local_ip]
|
||||||
|
s=-
|
||||||
|
c=IN IP[media_ip_type] [media_ip]
|
||||||
|
t=0 0
|
||||||
|
m=audio [media_port] RTP/AVP 0
|
||||||
|
a=rtpmap:0 PCMU/8000
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<recv request="ACK"
|
||||||
|
optional="true"
|
||||||
|
rtd="true"
|
||||||
|
crlf="true">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<recv request="BYE">
|
||||||
|
</recv>
|
||||||
|
|
||||||
|
<send>
|
||||||
|
<![CDATA[
|
||||||
|
|
||||||
|
SIP/2.0 200 OK
|
||||||
|
[last_Via:]
|
||||||
|
[last_From:]
|
||||||
|
[last_To:]
|
||||||
|
[last_Call-ID:]
|
||||||
|
[last_CSeq:]
|
||||||
|
Contact: <sip:[local_ip]:[local_port];transport=[transport]>
|
||||||
|
Content-Length: 0
|
||||||
|
|
||||||
|
]]>
|
||||||
|
</send>
|
||||||
|
|
||||||
|
<timewait milliseconds="4000"/>
|
||||||
|
|
||||||
|
|
||||||
|
<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
|
||||||
|
|
||||||
|
<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</scenario>
|
Reference in New Issue
Block a user