mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Add support for ICE/STUN/TURN in res_rtp_asterisk and chan_sip.
Review: https://reviewboard.asterisk.org/r/1891/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369517 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
4
res/pjproject/tests/automated/README.txt
Normal file
4
res/pjproject/tests/automated/README.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
This directory contains files to run automated/unattended tests for PJSIP.
|
||||
|
||||
See https://trac.pjsip.org/repos/wiki/AutomatedTesting for more info.
|
||||
|
354
res/pjproject/tests/automated/configure.py
Executable file
354
res/pjproject/tests/automated/configure.py
Executable file
@@ -0,0 +1,354 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import platform
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
PROG = "r" + "$Rev$".strip("$ ").replace("Rev: ", "")
|
||||
PYTHON = os.path.basename(sys.executable)
|
||||
build_type = ""
|
||||
vs_target = ""
|
||||
s60_target = ""
|
||||
no_test = False
|
||||
no_pjsua_test = False
|
||||
|
||||
#
|
||||
# Get gcc version
|
||||
#
|
||||
def gcc_version(gcc):
|
||||
proc = subprocess.Popen(gcc + " -v", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, shell=True)
|
||||
ver = ""
|
||||
while True:
|
||||
s = proc.stdout.readline()
|
||||
if not s:
|
||||
break
|
||||
if s.find("gcc version") >= 0:
|
||||
ver = s.split(None, 3)[2]
|
||||
break
|
||||
proc.wait()
|
||||
return "gcc-" + ver
|
||||
|
||||
#
|
||||
# Get Visual Studio info
|
||||
#
|
||||
class VSVersion:
|
||||
def __init__(self):
|
||||
self.version = "8"
|
||||
self.release = "2005"
|
||||
|
||||
proc = subprocess.Popen("cl", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
while True:
|
||||
s = proc.stdout.readline()
|
||||
if s=="":
|
||||
break
|
||||
pos = s.find("Version")
|
||||
if pos > 0:
|
||||
proc.wait()
|
||||
s = s[pos+8:]
|
||||
ver = s.split(None, 1)[0]
|
||||
major = ver[0:2]
|
||||
if major=="12":
|
||||
self.version = "6"
|
||||
self.release = "98"
|
||||
break
|
||||
elif major=="13":
|
||||
self.version = "7"
|
||||
self.release = "2003"
|
||||
break
|
||||
elif major=="14":
|
||||
self.version = "8"
|
||||
self.release = "2005"
|
||||
break
|
||||
elif major=="15":
|
||||
self.version = "9"
|
||||
self.release = "2008"
|
||||
break
|
||||
elif major=="16":
|
||||
self.version = "10"
|
||||
self.release = "2010"
|
||||
break
|
||||
else:
|
||||
self.version = "11"
|
||||
self.release = "2012"
|
||||
break
|
||||
proc.wait()
|
||||
self.vs_version = "vs" + self.version
|
||||
self.vs_release = "vs" + self.release
|
||||
|
||||
|
||||
#
|
||||
# Get S60 SDK info
|
||||
#
|
||||
class S60SDK:
|
||||
def __init__(self):
|
||||
self.epocroot = ""
|
||||
self.sdk = ""
|
||||
self.device = ""
|
||||
|
||||
# Check that EPOCROOT is set
|
||||
if not "EPOCROOT" in os.environ:
|
||||
sys.stderr.write("Error: EPOCROOT environment variable is not set\n")
|
||||
sys.exit(1)
|
||||
epocroot = os.environ["EPOCROOT"]
|
||||
# EPOCROOT must have trailing backslash
|
||||
if epocroot[-1] != "\\":
|
||||
epocroot = epocroot + "\\"
|
||||
os.environ["EPOCROOT"] = epocroot
|
||||
self.epocroot = epocroot
|
||||
self.sdk = sdk1 = epocroot.split("\\")[-2]
|
||||
self.device = "@" + self.sdk + ":com.nokia.s60"
|
||||
|
||||
# Check that correct device is set
|
||||
proc = subprocess.Popen("devices", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, shell=True)
|
||||
sdk2 = ""
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line.find("- default") > 0:
|
||||
sdk2 = line.split(":",1)[0]
|
||||
break
|
||||
proc.wait()
|
||||
|
||||
if sdk1 != sdk2:
|
||||
sys.stderr.write("Error: default SDK in device doesn't match EPOCROOT\n")
|
||||
sys.stderr.write("Default device SDK = '" + sdk2 + "'\n")
|
||||
sys.stderr.write("EPOCROOT SDK = '" + sdk1 + "'\n")
|
||||
sys.exit(1)
|
||||
|
||||
self.name = sdk2.replace("_", "-")
|
||||
|
||||
|
||||
|
||||
def replace_vars(text):
|
||||
global vs_target, s60_target, build_type, no_test, no_pjsua_test
|
||||
suffix = ""
|
||||
|
||||
os_info = platform.system() + platform.release() + "-" + platform.machine()
|
||||
|
||||
# osinfo
|
||||
s60sdk_var = None
|
||||
if build_type == "s60":
|
||||
s60sdk_var = S60SDK()
|
||||
os_info = s60sdk_var.name
|
||||
elif platform.system().lower() == "windows" or platform.system().lower() == "microsoft":
|
||||
if platform.system().lower() == "microsoft":
|
||||
os_info = platform.release() + "-" + platform.version() + "-" + platform.win32_ver()[2]
|
||||
elif platform.system().lower() == "linux":
|
||||
os_info = "-" + "-".join(platform.linux_distribution()[0:2])
|
||||
|
||||
# vs_target
|
||||
if not vs_target and text.find("$(VSTARGET)") >= 0:
|
||||
if build_type != "vs":
|
||||
sys.stderr.write("Warning: $(VSTARGET) only valid for Visual Studio\n")
|
||||
print "Enter Visual Studio vs_target name (e.g. Release, Debug) [Release]: ",
|
||||
vs_target = sys.stdin.readline().replace("\n", "").replace("\r", "")
|
||||
if not vs_target:
|
||||
vs_target = "Release"
|
||||
|
||||
# s60_target
|
||||
if not s60_target and text.find("$(S60TARGET)") >= 0:
|
||||
if build_type != "s60":
|
||||
sys.stderr.write("Warning: $(S60TARGET) only valid for S60\n")
|
||||
print "Enter S60 target name (e.g. \"gcce urel\") [gcce urel]: ",
|
||||
s60_target = sys.stdin.readline().replace("\n", "").replace("\r", "")
|
||||
if not s60_target:
|
||||
s60_target = "gcce urel"
|
||||
|
||||
# Suffix
|
||||
if build_type == "vs":
|
||||
suffix = "i386-Win32-vc8-" + vs_target
|
||||
elif build_type == "s60":
|
||||
suffix = s60sdk_var.name + "-" + s60_target.replace(" ", "-")
|
||||
elif build_type == "gnu":
|
||||
proc = subprocess.Popen("sh config.guess", cwd="../..",
|
||||
shell=True, stdout=subprocess.PIPE)
|
||||
suffix = proc.stdout.readline().rstrip(" \r\n")
|
||||
else:
|
||||
sys.stderr.write("Error: unsupported build type '" + build_type + "'\n")
|
||||
sys.exit(1)
|
||||
|
||||
while True:
|
||||
if text.find("$(PJSUA-TESTS)") >= 0:
|
||||
if no_test==False and no_pjsua_test==False:
|
||||
# Determine pjsua exe to use
|
||||
exe = "../../pjsip-apps/bin/pjsua-" + suffix
|
||||
proc = subprocess.Popen(PYTHON + " runall.py --list-xml -e " + exe,
|
||||
cwd="../pjsua",
|
||||
shell=True, stdout=subprocess.PIPE)
|
||||
content = proc.stdout.read()
|
||||
else:
|
||||
content = ""
|
||||
text = text.replace("$(PJSUA-TESTS)", content)
|
||||
elif text.find("$(GCC)") >= 0:
|
||||
text = text.replace("$(GCC)", gcc_version("gcc"))
|
||||
elif text.find("$(VS)") >= 0:
|
||||
vsver = VSVersion()
|
||||
text = text.replace("$(VS)", VSVersion().vs_release)
|
||||
elif text.find("$(VSTARGET)") >= 0:
|
||||
text = text.replace("$(VSTARGET)", vs_target)
|
||||
elif text.find("$(S60TARGET)") >= 0:
|
||||
text = text.replace("$(S60TARGET)", s60_target)
|
||||
elif text.find("$(S60TARGETNAME)") >= 0:
|
||||
text = text.replace("$(S60TARGETNAME)", s60_target.replace(" ", "-"))
|
||||
elif text.find("$(S60DEVICE)") >= 0:
|
||||
text = text.replace("$(S60DEVICE)", s60sdk_var.device)
|
||||
elif text.find("$(EPOCROOT)") >= 0:
|
||||
text = text.replace("$(EPOCROOT)", s60sdk_var.epocroot)
|
||||
elif text.find("$(DISABLED)") >= 0:
|
||||
text = text.replace("$(DISABLED)", "0")
|
||||
elif text.find("$(IPPROOT)") >= 0:
|
||||
if not os.environ.has_key("IPPROOT"):
|
||||
sys.stderr.write("Error: environment variable IPPROOT is needed but not set\n")
|
||||
sys.exit(1)
|
||||
text = text.replace("$(IPPROOT)", os.environ["IPPROOT"])
|
||||
elif text.find("$(IPPSAMPLES)") >= 0:
|
||||
if not os.environ.has_key("IPPSAMPLES"):
|
||||
sys.stderr.write("Error: environment variable IPPSAMPLES is needed but not set\n")
|
||||
sys.exit(1)
|
||||
text = text.replace("$(IPPSAMPLES)", os.environ["IPPSAMPLES"])
|
||||
elif text.find("$(IPPARCH)") >= 0:
|
||||
if not os.environ.has_key("IPPARCH"):
|
||||
text = text.replace("$(IPPARCH)", "")
|
||||
else:
|
||||
text = text.replace("$(IPPARCH)", os.environ["IPPARCH"])
|
||||
elif text.find("$(OS)") >= 0:
|
||||
text = text.replace("$(OS)", os_info)
|
||||
elif text.find("$(SUFFIX)") >= 0:
|
||||
text = text.replace("$(SUFFIX)", suffix)
|
||||
elif text.find("$(HOSTNAME)") >= 0:
|
||||
text = text.replace("$(HOSTNAME)", socket.gethostname())
|
||||
elif text.find("$(PJDIR)") >= 0:
|
||||
wdir = os.path.join(os.getcwd(), "../..")
|
||||
wdir = os.path.normpath(wdir)
|
||||
text = text.replace("$(PJDIR)", wdir)
|
||||
elif text.find("$(NOP)") >= 0:
|
||||
if platform.system().lower() == "windows" or platform.system().lower() == "microsoft":
|
||||
cmd = "CMD /C echo Success"
|
||||
else:
|
||||
cmd = "echo Success"
|
||||
text = text.replace("$(NOP)", cmd)
|
||||
elif text.find("$(NOTEST)") >= 0:
|
||||
if no_test:
|
||||
str = '"1"'
|
||||
else:
|
||||
str = '"0"'
|
||||
text = text.replace("$(NOTEST)", str)
|
||||
else:
|
||||
break
|
||||
return text
|
||||
|
||||
|
||||
def main(args):
|
||||
global vs_target, s60_target, build_type, no_test, no_pjsua_test
|
||||
output = sys.stdout
|
||||
usage = """Usage: configure.py [OPTIONS] scenario_template_file
|
||||
|
||||
Where OPTIONS:
|
||||
-o FILE Output to file, otherwise to stdout.
|
||||
-t TYPE Specify build type. If not specified, it will be
|
||||
asked if necessary. Values are:
|
||||
vs: Visual Studio
|
||||
gnu: Makefile based
|
||||
s60: Symbian S60
|
||||
-vstarget TARGETNAME Specify Visual Studio target name if build type is set
|
||||
to vs. If not specified then it will be asked.
|
||||
Sample target names:
|
||||
- Debug
|
||||
- Release
|
||||
- or any other target in the project file
|
||||
-s60target TARGETNAME Specify S60 target name if build type is set to s60.
|
||||
If not specified then it will be asked. Sample target
|
||||
names:
|
||||
- "gcce udeb"
|
||||
- "gcce urel"
|
||||
-notest Disable all tests in the scenario.
|
||||
-nopjsuatest Disable pjsua tests in the scenario.
|
||||
"""
|
||||
|
||||
args.pop(0)
|
||||
while len(args):
|
||||
if args[0]=='-o':
|
||||
args.pop(0)
|
||||
if len(args):
|
||||
output = open(args[0], "wt")
|
||||
args.pop(0)
|
||||
else:
|
||||
sys.stderr.write("Error: needs value for -o\n")
|
||||
sys.exit(1)
|
||||
elif args[0]=='-vstarget':
|
||||
args.pop(0)
|
||||
if len(args):
|
||||
vs_target = args[0]
|
||||
args.pop(0)
|
||||
else:
|
||||
sys.stderr.write("Error: needs value for -vstarget\n")
|
||||
sys.exit(1)
|
||||
elif args[0]=='-s60target':
|
||||
args.pop(0)
|
||||
if len(args):
|
||||
s60_target = args[0]
|
||||
args.pop(0)
|
||||
else:
|
||||
sys.stderr.write("Error: needs value for -s60target\n")
|
||||
sys.exit(1)
|
||||
elif args[0]=='-t':
|
||||
args.pop(0)
|
||||
if len(args):
|
||||
build_type = args[0].lower()
|
||||
args.pop(0)
|
||||
else:
|
||||
sys.stderr.write("Error: needs value for -t\n")
|
||||
sys.exit(1)
|
||||
if not ["vs", "gnu", "s60"].count(build_type):
|
||||
sys.stderr.write("Error: invalid -t argument value\n")
|
||||
sys.exit(1)
|
||||
elif args[0]=='-notest' or args[0]=='-notests':
|
||||
args.pop(0)
|
||||
no_test = True
|
||||
elif args[0]=='-nopjsuatest' or args[0]=='-nopjsuatests':
|
||||
args.pop(0)
|
||||
no_pjsua_test = True
|
||||
else:
|
||||
break
|
||||
|
||||
if len(args) != 1:
|
||||
sys.stderr.write(usage + "\n")
|
||||
return 1
|
||||
|
||||
if not build_type:
|
||||
defval = "vs"
|
||||
if "SHELL" in os.environ:
|
||||
shell = os.environ["SHELL"]
|
||||
if shell.find("sh") > -1:
|
||||
defval = "gnu"
|
||||
print "Enter the build type (values: vs, gnu, s60) [%s]: " % (defval),
|
||||
build_type = sys.stdin.readline().replace("\n", "").replace("\r", "")
|
||||
if not build_type:
|
||||
build_type = defval
|
||||
|
||||
|
||||
tpl_file = args[len(args)-1]
|
||||
if not os.path.isfile(tpl_file):
|
||||
print "Error: unable to find template file '%s'" % (tpl_file)
|
||||
return 1
|
||||
|
||||
f = open(tpl_file, "r")
|
||||
tpl = f.read()
|
||||
f.close()
|
||||
|
||||
tpl = replace_vars(tpl)
|
||||
output.write(tpl)
|
||||
if output != sys.stdout:
|
||||
output.close()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
rc = main(sys.argv)
|
||||
sys.exit(rc)
|
||||
|
28
res/pjproject/tests/automated/gnu-ipp.xml.template
Normal file
28
res/pjproject/tests/automated/gnu-ipp.xml.template
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
<Submit group="Experimental" build="$(SUFFIX)-$(GCC)-IPP" disabled="$(DISABLED)" >
|
||||
<Update />
|
||||
<FileWrite file="user.mak">
|
||||
<![CDATA[
|
||||
# Written by ccdash
|
||||
export CFLAGS += -Wno-unused-label -g
|
||||
]]>
|
||||
</FileWrite>
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_HAS_IPV6 1
|
||||
#define PJMEDIA_HAS_G7221_CODEC 0
|
||||
#define PJMEDIA_HAS_INTEL_IPP 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd='./aconfigure --enable-ipp --with-ipp="$(IPPROOT)" --with-ipp-samples="$(IPPSAMPLES)" --with-ipp-arch=$(IPPARCH)' />
|
||||
<Build cmd="make dep && make clean && make" />
|
||||
<Test name="pjlib-test" wdir="pjlib/bin" cmd="./pjlib-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjlib-util-test" wdir="pjlib-util/bin" cmd="./pjlib-util-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjnath-test" wdir="pjnath/bin" cmd="./pjnath-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjmedia-test" wdir="pjmedia/bin" cmd="./pjmedia-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjsip-test" wdir="pjsip/bin" cmd="./pjsip-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
$(PJSUA-TESTS)
|
||||
</Submit>
|
||||
</Scenario>
|
29
res/pjproject/tests/automated/gnu.xml.template
Normal file
29
res/pjproject/tests/automated/gnu.xml.template
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
|
||||
<Submit group="Experimental" build="$(SUFFIX)-$(GCC)" exclude="(.*amr.*)">
|
||||
<Update />
|
||||
<FileWrite file="user.mak">
|
||||
<![CDATA[
|
||||
# Written by ccdash
|
||||
export CFLAGS += -Wno-unused-label -g
|
||||
]]>
|
||||
</FileWrite>
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_HAS_IPV6 1
|
||||
#define PJMEDIA_HAS_G7221_CODEC 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="./aconfigure" />
|
||||
<Build cmd="make dep && make clean && make" />
|
||||
<Test name="pjlib-test" wdir="pjlib/bin" cmd="./pjlib-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjlib-util-test" wdir="pjlib-util/bin" cmd="./pjlib-util-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjnath-test" wdir="pjnath/bin" cmd="./pjnath-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjmedia-test" wdir="pjmedia/bin" cmd="./pjmedia-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
<Test name="pjsip-test" wdir="pjsip/bin" cmd="./pjsip-test-$(SUFFIX)" disabled=$(NOTEST) />
|
||||
$(PJSUA-TESTS)
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
23
res/pjproject/tests/automated/iphone.xml.template
Normal file
23
res/pjproject/tests/automated/iphone.xml.template
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
|
||||
<Submit group="Experimental" build="iPhoneOS-default">
|
||||
<Update />
|
||||
<FileWrite file="user.mak">
|
||||
<![CDATA[
|
||||
# Written by ccdash
|
||||
export CFLAGS += -Wno-unused-label -g
|
||||
]]>
|
||||
</FileWrite>
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_CONFIG_IPHONE 1
|
||||
#include <pj/config_site_sample.h>
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="./configure-iphone" />
|
||||
<Build cmd="make distclean && make dep && make clean && make" />
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
24
res/pjproject/tests/automated/msvc.xml.template
Normal file
24
res/pjproject/tests/automated/msvc.xml.template
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
|
||||
<Submit group="Experimental" build="$(OS)-$(VS)-$(VSTARGET)-default" exclude="(.*amr.*)">
|
||||
<Update />
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_HAS_IPV6 1
|
||||
#define PJMEDIA_HAS_G7221_CODEC 1
|
||||
#define PJ_TODO(x)
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c echo success" />
|
||||
<Build cmd='vcbuild.exe /nologo /nohtmllog /nocolor /rebuild pjproject-vs8.sln "$(VSTARGET)|Win32"' />
|
||||
<Test name="pjlib-test" info="" wdir="pjlib/bin" cmd="pjlib-test-i386-Win32-vc8-$(VSTARGET)" disabled=$(NOTEST)/>
|
||||
<Test name="pjlib-util-test" info="" wdir="pjlib-util/bin" cmd="pjlib-util-test-i386-Win32-vc8-$(VSTARGET)" disabled=$(NOTEST) />
|
||||
<Test name="pjnath-test" info="" wdir="pjnath/bin" cmd="pjnath-test-i386-Win32-vc8-$(VSTARGET)" disabled=$(NOTEST) />
|
||||
<Test name="pjmedia-test" info="" wdir="pjmedia/bin" cmd="pjmedia-test-i386-Win32-vc8-$(VSTARGET)" disabled=$(NOTEST) />
|
||||
<Test name="pjsip-test" info="" wdir="pjsip/bin" cmd="pjsip-test-i386-Win32-vc8-$(VSTARGET)" disabled=$(NOTEST) />
|
||||
$(PJSUA-TESTS)
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
46
res/pjproject/tests/automated/prepare.xml.template
Normal file
46
res/pjproject/tests/automated/prepare.xml.template
Normal file
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)/tests/automated">
|
||||
|
||||
<Submit group="Experimental" build="Test-Preparation">
|
||||
<Configure cmd="$(NOP)" />
|
||||
<Build cmd="$(NOP)" />
|
||||
|
||||
<!-- GNU Makefile based scenario
|
||||
Requirement:
|
||||
- none
|
||||
-->
|
||||
<Test name="Configuring GNU scenario" cmd="python configure.py -t gnu -o gnu.xml gnu.xml.template" />
|
||||
|
||||
<!-- GNU Makefile with Intel IPP scenario.
|
||||
Requirements:
|
||||
- IPPROOT
|
||||
- IPPSAMPLES
|
||||
- IPPARCH (optional)
|
||||
|
||||
-->
|
||||
<Test name="Configuring GNU IPP scenario" cmd="python configure.py -t gnu -o gnu-ipp.xml gnu-ipp.xml.template" />
|
||||
|
||||
<!-- iPhone target.
|
||||
Requriement(s):
|
||||
- valid SDK is installed
|
||||
|
||||
-->
|
||||
<Test name="Configuring iPhone scenario" cmd="python configure.py -t gnu -o iphone.xml iphone.xml.template" />
|
||||
|
||||
<!-- MSVC target.
|
||||
Requirements:
|
||||
- Build from VS successfully
|
||||
- VS paths are set
|
||||
|
||||
-->
|
||||
<Test name="Configuring Visual Studio for Win32" cmd="python configure.py -t vs -vstarget Release -o msvc-win32.xml -nopjsuatest msvc.xml.template" />
|
||||
|
||||
<!-- Symbian target.
|
||||
Requirement:
|
||||
- EPOCROOT (modify below)
|
||||
-->
|
||||
<Test name="Configuring Symbian scenario" cmd='CMD /C SET EPOCROOT=\S60\devices\S60_5th_Edition_SDK_v1.0&& devices -setdefault @S60_5th_Edition_SDK_v1.0:com.nokia.s60&& python configure.py -t s60 -s60target "gcce urel" -o symbian.xml symbian.xml.template' />
|
||||
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
140
res/pjproject/tests/automated/run_continuous.py
Executable file
140
res/pjproject/tests/automated/run_continuous.py
Executable file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import datetime
|
||||
import ccdash
|
||||
|
||||
INTERVAL = 300
|
||||
DELAY = 0
|
||||
ONCE = False
|
||||
SUFFIX = ""
|
||||
FORCE = False
|
||||
|
||||
def run_scenarios(scenarios, group):
|
||||
# Run each scenario
|
||||
rc = 0
|
||||
for scenario in scenarios:
|
||||
argv = []
|
||||
argv.append("ccdash.py")
|
||||
argv.append("scenario")
|
||||
argv.append(scenario)
|
||||
argv.append("--group")
|
||||
argv.append(group)
|
||||
thisrc = ccdash.main(argv)
|
||||
if rc==0 and thisrc:
|
||||
rc = thisrc
|
||||
return rc
|
||||
|
||||
|
||||
def usage():
|
||||
print """Periodically monitor working directory for Continuous and Nightly builds
|
||||
|
||||
Usage:
|
||||
run_continuous.py [options] scenario1.xml [scenario2.xml ...]
|
||||
|
||||
options:
|
||||
These are options which will be processed by run_continuous.py:
|
||||
|
||||
--delay MIN Delay both Continuous and Nightly builds by MIN minutes.
|
||||
This is useful to coordinate the build with other build
|
||||
machines. By default, Continuous build will be done right
|
||||
after changes are detected, and Nightly build will be done
|
||||
at 00:00 GMT. MIN is a float number.
|
||||
|
||||
--once Just run one loop to see if anything needs to be done and
|
||||
if so just do it once. Quit after that.
|
||||
|
||||
--suffix SFX Set group suffix to SFX. For example, if SFX is "-2.x", then
|
||||
tests will be submitted to "Nightly-2.x", "Continuous-2.x",
|
||||
and "Experimental-2.x"
|
||||
|
||||
--force Force running the test even when nothing has changed.
|
||||
"""
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv)<=1 or sys.argv[1]=="-h" or sys.argv[1]=="--h" or sys.argv[1]=="--help" or sys.argv[1]=="/h":
|
||||
usage()
|
||||
|
||||
# Splice list
|
||||
scenarios = []
|
||||
i = 1
|
||||
while i < len(sys.argv):
|
||||
if sys.argv[i]=="--delay":
|
||||
i = i + 1
|
||||
if i >= len(sys.argv):
|
||||
print "Error: missing argument"
|
||||
sys.exit(1)
|
||||
DELAY = float(sys.argv[i]) * 60
|
||||
print "Delay is set to %f minute(s)" % (DELAY / 60)
|
||||
elif sys.argv[i]=="--suffix":
|
||||
i = i + 1
|
||||
if i >= len(sys.argv):
|
||||
print "Error: missing argument"
|
||||
sys.exit(1)
|
||||
SUFFIX = sys.argv[i]
|
||||
print "Suffix is set to %s" % (SUFFIX)
|
||||
elif sys.argv[i]=="--once":
|
||||
ONCE = True
|
||||
elif sys.argv[i]=="--force":
|
||||
FORCE = True
|
||||
else:
|
||||
# Check if scenario exists
|
||||
scenario = sys.argv[i]
|
||||
if not os.path.exists(scenario):
|
||||
print "Error: file " + scenario + " does not exist"
|
||||
sys.exit(1)
|
||||
scenarios.append(scenario)
|
||||
print "Scenario %s added" % (scenario)
|
||||
i = i + 1
|
||||
|
||||
if len(scenarios) < 1:
|
||||
print "Error: scenario is required"
|
||||
sys.exit(1)
|
||||
|
||||
# Current date
|
||||
utc = time.gmtime(None)
|
||||
day = utc.tm_mday
|
||||
|
||||
# Loop foreva
|
||||
while True:
|
||||
argv = []
|
||||
|
||||
# Anything changed recently?
|
||||
argv.append("ccdash.py")
|
||||
argv.append("status")
|
||||
argv.append("-w")
|
||||
argv.append("../..")
|
||||
rc = ccdash.main(argv)
|
||||
|
||||
utc = time.gmtime(None)
|
||||
|
||||
if utc.tm_mday != day or rc != 0 or FORCE:
|
||||
group = ""
|
||||
if utc.tm_mday != day:
|
||||
day = utc.tm_mday
|
||||
group = "Nightly" + SUFFIX
|
||||
elif rc != 0:
|
||||
group = "Continuous" + SUFFIX
|
||||
else:
|
||||
group = "Experimental" + SUFFIX
|
||||
if DELAY > 0:
|
||||
print "Will run %s after %f s.." % (group, DELAY)
|
||||
time.sleep(DELAY)
|
||||
rc = run_scenarios(scenarios, group)
|
||||
msg = str(datetime.datetime.now()) + \
|
||||
": done running " + group + \
|
||||
"tests, will check again in " + str(INTERVAL) + "s.."
|
||||
if ONCE:
|
||||
sys.exit(0)
|
||||
else:
|
||||
# Nothing changed
|
||||
msg = str(datetime.datetime.now()) + \
|
||||
": No update, will check again in " + str(INTERVAL) + "s.."
|
||||
if ONCE:
|
||||
sys.exit(1)
|
||||
|
||||
print msg
|
||||
time.sleep(INTERVAL)
|
||||
|
11
res/pjproject/tests/automated/run_scenario.py
Normal file
11
res/pjproject/tests/automated/run_scenario.py
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
import ccdash
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.argv[0] = "ccdash.py"
|
||||
sys.argv.insert(1, "scenario")
|
||||
rc = ccdash.main(sys.argv)
|
||||
sys.exit(rc)
|
||||
|
||||
|
78
res/pjproject/tests/automated/symbian-aps.xml.template
Normal file
78
res/pjproject/tests/automated/symbian-aps.xml.template
Normal file
@@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
<!-- *********************************************************
|
||||
** This file contains scenario for APS and APS-Direct **
|
||||
********************************************************* -->
|
||||
|
||||
<!-- ******************************
|
||||
** APS **
|
||||
****************************** -->
|
||||
<Submit group="Experimental" build="$(OS)-$(S60TARGETNAME)-APS" >
|
||||
<Update />
|
||||
<!-- Configure config_site.h -->
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 1
|
||||
#define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
|
||||
#include <pj/config_site_sample.h>
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Configure symbian_ua.mmp -->
|
||||
<FileWrite file="build.symbian/symbian_ua.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 1
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 0
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Configure symbian_ua_gui.mmp -->
|
||||
<FileWrite file="pjsip-apps/src/symbian_ua_gui/group/symbian_ua_gui.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 1
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 0
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c echo success" />
|
||||
<Build wdir="build.symbian" cmd='cmd /C "bldmake bldfiles && abld reallyclean $(S60TARGET) && abld build $(S60TARGET)"' />
|
||||
</Submit>
|
||||
|
||||
|
||||
<!-- ******************************
|
||||
** APS-Direct **
|
||||
****************************** -->
|
||||
<Submit group="Experimental" build="$(OS)-$(S60TARGETNAME)-APS-Direct" >
|
||||
<Update />
|
||||
<!-- Configure config_site.h -->
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_CONFIG_NOKIA_APS_DIRECT
|
||||
#include <pj/config_site_sample.h>
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c echo success" />
|
||||
<Build wdir="build.symbian" cmd='cmd /C "bldmake bldfiles && abld reallyclean $(S60TARGET) && abld build $(S60TARGET)"' />
|
||||
|
||||
<!-- Restore symbian_ua.mmp -->
|
||||
<FileWrite file="build.symbian/symbian_ua.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Restore symbian_ua_gui.mmp -->
|
||||
<FileWrite file="pjsip-apps/src/symbian_ua_gui/group/symbian_ua_gui.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
||||
|
79
res/pjproject/tests/automated/symbian-vas.xml.template
Normal file
79
res/pjproject/tests/automated/symbian-vas.xml.template
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
<!-- *********************************************************
|
||||
** This file contains scenario for VAS and VAS-Direct **
|
||||
********************************************************* -->
|
||||
|
||||
<!-- ******************************
|
||||
** VAS **
|
||||
****************************** -->
|
||||
<Submit group="Experimental" build="$(OS)-$(S60TARGETNAME)-VAS1" >
|
||||
<Update />
|
||||
<!-- Configure config_site.h -->
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJMEDIA_AUDIO_DEV_HAS_SYMB_VAS 1
|
||||
#define PJMEDIA_AUDIO_DEV_HAS_SYMB_APS 0
|
||||
#define PJMEDIA_AUDIO_DEV_HAS_SYMB_MDA 0
|
||||
#include <pj/config_site_sample.h>
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Configure symbian_ua.mmp -->
|
||||
<FileWrite file="build.symbian/symbian_ua.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 1
|
||||
#define SND_HAS_MDA 0
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Configure symbian_ua_gui.mmp -->
|
||||
<FileWrite file="pjsip-apps/src/symbian_ua_gui/group/symbian_ua_gui.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 1
|
||||
#define SND_HAS_MDA 0
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c echo success" />
|
||||
<Build wdir="build.symbian" cmd='cmd /C "bldmake bldfiles && abld reallyclean $(S60TARGET) && abld build $(S60TARGET)"' />
|
||||
</Submit>
|
||||
|
||||
|
||||
<!-- ******************************
|
||||
** VAS-Direct **
|
||||
****************************** -->
|
||||
<Submit group="Experimental" build="$(OS)-$(S60TARGETNAME)-VAS1-Direct" >
|
||||
<Update />
|
||||
<!-- Configure config_site.h -->
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#define PJ_CONFIG_NOKIA_VAS_DIRECT
|
||||
#include <pj/config_site_sample.h>
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c echo success" />
|
||||
<Build wdir="build.symbian" cmd='cmd /C "bldmake bldfiles && abld reallyclean $(S60TARGET) && abld build $(S60TARGET)"' />
|
||||
|
||||
<!-- Restore symbian_ua.mmp -->
|
||||
<FileWrite file="build.symbian/symbian_ua.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
<!-- Restore symbian_ua_gui.mmp -->
|
||||
<FileWrite file="pjsip-apps/src/symbian_ua_gui/group/symbian_ua_gui.mmp" replace_begin="// =BEGIN" replace_end="// =END">
|
||||
<![CDATA[
|
||||
#define SND_HAS_APS 0
|
||||
#define SND_HAS_VAS 0
|
||||
#define SND_HAS_MDA 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
|
||||
</Submit>
|
||||
|
||||
</Scenario>
|
||||
|
20
res/pjproject/tests/automated/symbian.xml.template
Normal file
20
res/pjproject/tests/automated/symbian.xml.template
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Scenario site="$(HOSTNAME)" url="http://my.cdash.org/submit.php?project=PJSIP" wdir="$(PJDIR)">
|
||||
<!-- Symbian S60 default -->
|
||||
<Submit group="Experimental" build="$(OS)-$(S60TARGETNAME)-default" >
|
||||
<Update disabled="1" />
|
||||
<FileWrite file="pjlib/include/pj/config_site.h">
|
||||
<![CDATA[
|
||||
/* Written by ccdash */
|
||||
#include <pj/config_site_sample.h>
|
||||
#undef PJ_HAS_IPV6
|
||||
#define PJ_HAS_IPV6 1
|
||||
#undef PJMEDIA_HAS_G7221_CODEC
|
||||
#define PJMEDIA_HAS_G7221_CODEC 1
|
||||
]]>
|
||||
</FileWrite>
|
||||
<Configure cmd="cmd /c devices -setdefault $(S60DEVICE)" />
|
||||
<Build wdir="build.symbian" cmd='cmd /C "SET EPOCROOT=$(EPOCROOT)&& bldmake bldfiles && abld reallyclean $(S60TARGET) && abld build $(S60TARGET)"' />
|
||||
</Submit>
|
||||
</Scenario>
|
||||
|
33
res/pjproject/tests/automated/testvars.template
Normal file
33
res/pjproject/tests/automated/testvars.template
Normal file
@@ -0,0 +1,33 @@
|
||||
Variables:
|
||||
-----------------------------
|
||||
DISABLED = "$(DISABLED)"
|
||||
GCC = "$(GCC)"
|
||||
HOSTNAME = "$(HOSTNAME)"
|
||||
OS = "$(OS)"
|
||||
PJDIR = "$(PJDIR)"
|
||||
SUFFIX = "$(SUFFIX)"
|
||||
NOTEST = "$(NOTEST)"
|
||||
|
||||
S60 only:
|
||||
------------------------------
|
||||
S60TARGET = "$(S60TARGET)"
|
||||
S60TARGETNAME = "$(S60TARGETNAME)"
|
||||
S60DEVICE = "$(S60DEVICE)"
|
||||
EPOCROOT = "$(EPOCROOT)"
|
||||
|
||||
VS only:
|
||||
------------------------------
|
||||
VS = "$(VS)"
|
||||
VSTARGET = "$(VSTARGET)"
|
||||
|
||||
PJSUA-TESTS:
|
||||
------------------------------
|
||||
$(PJSUA-TESTS)
|
||||
------------------------------
|
||||
|
||||
OTHER:
|
||||
------------------------------
|
||||
IPPROOT
|
||||
IPPSAMPLES
|
||||
IPPARCH
|
||||
NOP (cmdline to do nothing)
|
59
res/pjproject/tests/cdash/README.TXT
Normal file
59
res/pjproject/tests/cdash/README.TXT
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
PJSIP CDASH AUTOMATED TESTS
|
||||
--------------------------------
|
||||
|
||||
|
||||
1. What is this
|
||||
|
||||
This directory contains the scripts to run the automated, Python based tests
|
||||
of PJSIP source codes, across platforms, and submit the test results to a CDash
|
||||
test monitoring dashboard.
|
||||
|
||||
Stuffs that are included in the test scope:
|
||||
- configure (for GNU platforms, e.g. Linux, msys, and MacOS X)
|
||||
- build
|
||||
- standard unit tests (pjlib-test, pjsip-test, etc.)
|
||||
- pjsua's Python based blackbox tests
|
||||
|
||||
|
||||
2. Requirements
|
||||
|
||||
To run this test, you will need:
|
||||
- Python (2.4 or later)
|
||||
- curl (http://curl.haxx.se)
|
||||
- a CDash server to receive test submissions (http://www.cdash.org)
|
||||
- ccdash to submit the tests (http://trac.pjsip.org/ccdash)
|
||||
|
||||
|
||||
3. Configuration
|
||||
|
||||
Create a Python configuration file by copying from "cfg_site_sample.py".
|
||||
Save it as "cfg_site.py". You may create more than one configurations for your
|
||||
site and save them as different files.
|
||||
|
||||
|
||||
4. Running
|
||||
|
||||
To execute tests for GNU based targets:
|
||||
|
||||
$ python main.py cfg_gnu
|
||||
|
||||
|
||||
To execute tests for MSVC based target:
|
||||
|
||||
$ python main.py cfg_msvc
|
||||
|
||||
To execute tests for Symbian target:
|
||||
|
||||
$ python main.py cfg_symbian
|
||||
|
||||
|
||||
If you have a different site configuration file, you may specify it in the
|
||||
arguments, e.g.:
|
||||
|
||||
$ python main.py cfg_gnu my_site_config
|
||||
|
||||
For more information you can also pass "-h" or "--help", e.g.:
|
||||
|
||||
$ python main.py cfg_gnu --help
|
||||
|
501
res/pjproject/tests/cdash/builder.py
Normal file
501
res/pjproject/tests/cdash/builder.py
Normal file
@@ -0,0 +1,501 @@
|
||||
#
|
||||
# builder.py - PJSIP test scenarios builder
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
import ccdash
|
||||
import os
|
||||
import platform
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
class Operation:
|
||||
"""\
|
||||
The Operation class describes the individual ccdash operation to be
|
||||
performed.
|
||||
|
||||
"""
|
||||
# Types:
|
||||
UPDATE = "update" # Update operation
|
||||
CONFIGURE = "configure" # Configure operation
|
||||
BUILD = "build" # Build operation
|
||||
TEST = "test" # Unit test operation
|
||||
|
||||
def __init__(self, type, cmdline, name="", wdir=""):
|
||||
self.type = type
|
||||
self.cmdline = cmdline
|
||||
self.name = name
|
||||
self.wdir = wdir
|
||||
if self.type==self.TEST and not self.name:
|
||||
raise "name required for tests"
|
||||
|
||||
def encode(self, base_dir):
|
||||
s = [self.type]
|
||||
if self.type == self.TEST:
|
||||
s.append(self.name)
|
||||
if self.type != self.UPDATE:
|
||||
s.append(self.cmdline)
|
||||
s.append("-w")
|
||||
if self.wdir:
|
||||
s.append(base_dir + "/" + self.wdir)
|
||||
else:
|
||||
s.append(base_dir)
|
||||
return s
|
||||
|
||||
|
||||
#
|
||||
# Update operation
|
||||
#
|
||||
update_ops = [Operation(Operation.UPDATE, "")]
|
||||
|
||||
#
|
||||
# The standard library tests (e.g. pjlib-test, pjsip-test, etc.)
|
||||
#
|
||||
std_test_ops= [
|
||||
Operation(Operation.TEST, "./pjlib-test$SUFFIX", name="pjlib test",
|
||||
wdir="pjlib/bin"),
|
||||
Operation(Operation.TEST, "./pjlib-util-test$SUFFIX",
|
||||
name="pjlib-util test", wdir="pjlib-util/bin"),
|
||||
Operation(Operation.TEST, "./pjnath-test$SUFFIX", name="pjnath test",
|
||||
wdir="pjnath/bin"),
|
||||
Operation(Operation.TEST, "./pjmedia-test$SUFFIX", name="pjmedia test",
|
||||
wdir="pjmedia/bin"),
|
||||
Operation(Operation.TEST, "./pjsip-test$SUFFIX", name="pjsip test",
|
||||
wdir="pjsip/bin")
|
||||
]
|
||||
|
||||
#
|
||||
# These are pjsua Python based unit test operations
|
||||
#
|
||||
def build_pjsua_test_ops(pjsua_exe=""):
|
||||
ops = []
|
||||
if pjsua_exe:
|
||||
exe = " -e ../../pjsip-apps/bin/" + pjsua_exe
|
||||
else:
|
||||
exe = ""
|
||||
cwd = os.getcwd()
|
||||
os.chdir("../pjsua")
|
||||
os.system("python runall.py --list > list")
|
||||
f = open("list", "r")
|
||||
for e in f:
|
||||
e = e.rstrip("\r\n ")
|
||||
(mod,param) = e.split(None,2)
|
||||
name = mod[4:mod.find(".py")] + "_" + \
|
||||
param[param.find("/")+1:param.find(".py")]
|
||||
ops.append(Operation(Operation.TEST, "python run.py" + exe + " " + \
|
||||
e, name=name, wdir="tests/pjsua"))
|
||||
f.close()
|
||||
os.remove("list")
|
||||
os.chdir(cwd)
|
||||
return ops
|
||||
|
||||
#
|
||||
# Get gcc version
|
||||
#
|
||||
def gcc_version(gcc):
|
||||
proc = subprocess.Popen(gcc + " -v", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, shell=True)
|
||||
ver = ""
|
||||
while True:
|
||||
s = proc.stdout.readline()
|
||||
if not s:
|
||||
break
|
||||
if s.find("gcc version") >= 0:
|
||||
ver = s.split(None, 3)[2]
|
||||
break
|
||||
proc.wait()
|
||||
return "gcc-" + ver
|
||||
|
||||
#
|
||||
# Get Visual Studio version
|
||||
#
|
||||
def vs_get_version():
|
||||
proc = subprocess.Popen("cl", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
while True:
|
||||
s = proc.stdout.readline()
|
||||
if s=="":
|
||||
break
|
||||
pos = s.find("Version")
|
||||
if pos > 0:
|
||||
proc.wait()
|
||||
s = s[pos+8:]
|
||||
ver = s.split(None, 1)[0]
|
||||
major = ver[0:2]
|
||||
if major=="12":
|
||||
return "vs6"
|
||||
elif major=="13":
|
||||
return "vs2003"
|
||||
elif major=="14":
|
||||
return "vs2005"
|
||||
elif major=="15":
|
||||
return "vs2008"
|
||||
else:
|
||||
return "vs-" + major
|
||||
proc.wait()
|
||||
return "vs-unknown"
|
||||
|
||||
|
||||
#
|
||||
# Test config
|
||||
#
|
||||
class BaseConfig:
|
||||
def __init__(self, base_dir, url, site, group, options=None):
|
||||
self.base_dir = base_dir
|
||||
self.url = url
|
||||
self.site = site
|
||||
self.group = group
|
||||
self.options = options
|
||||
|
||||
#
|
||||
# Base class for test configurator
|
||||
#
|
||||
class TestBuilder:
|
||||
def __init__(self, config, build_config_name="",
|
||||
user_mak="", config_site="", exclude=[], not_exclude=[]):
|
||||
self.config = config # BaseConfig instance
|
||||
self.build_config_name = build_config_name # Optional build suffix
|
||||
self.user_mak = user_mak # To be put in user.mak
|
||||
self.config_site = config_site # To be put in config_s..
|
||||
self.saved_user_mak = "" # To restore user.mak
|
||||
self.saved_config_site = "" # To restore config_s..
|
||||
self.exclude = exclude # List of exclude pattern
|
||||
self.not_exclude = not_exclude # List of include pattern
|
||||
self.ccdash_args = [] # ccdash cmd line
|
||||
|
||||
def stamp(self):
|
||||
return time.strftime("%Y%m%d-%H%M", time.localtime())
|
||||
|
||||
def pre_action(self):
|
||||
# Override user.mak
|
||||
name = self.config.base_dir + "/user.mak"
|
||||
if os.access(name, os.F_OK):
|
||||
f = open(name, "r")
|
||||
self.saved_user_mak = f.read()
|
||||
f.close()
|
||||
if True:
|
||||
f = open(name, "w")
|
||||
f.write(self.user_mak)
|
||||
f.close()
|
||||
# Override config_site.h
|
||||
name = self.config.base_dir + "/pjlib/include/pj/config_site.h"
|
||||
if os.access(name, os.F_OK):
|
||||
f = open(name, "r")
|
||||
self.saved_config_site= f.read()
|
||||
f.close()
|
||||
if True:
|
||||
f = open(name, "wt")
|
||||
f.write(self.config_site)
|
||||
f.close()
|
||||
|
||||
|
||||
def post_action(self):
|
||||
# Restore user.mak
|
||||
name = self.config.base_dir + "/user.mak"
|
||||
f = open(name, "wt")
|
||||
f.write(self.saved_user_mak)
|
||||
f.close()
|
||||
# Restore config_site.h
|
||||
name = self.config.base_dir + "/pjlib/include/pj/config_site.h"
|
||||
f = open(name, "wt")
|
||||
f.write(self.saved_config_site)
|
||||
f.close()
|
||||
|
||||
def build_tests(self):
|
||||
# This should be overridden by subclasses
|
||||
pass
|
||||
|
||||
def execute(self):
|
||||
if len(self.ccdash_args)==0:
|
||||
self.build_tests()
|
||||
self.pre_action()
|
||||
mandatory_op = ["update", "configure", "build"]
|
||||
counter = 0
|
||||
for a in self.ccdash_args:
|
||||
# Check if this test is in exclusion list
|
||||
fullcmd = " ".join(a)
|
||||
excluded = False
|
||||
included = False
|
||||
for pat in self.exclude:
|
||||
if pat and re.search(pat, fullcmd) != None:
|
||||
excluded = True
|
||||
break
|
||||
if excluded:
|
||||
for pat in self.not_exclude:
|
||||
if pat and re.search(pat, fullcmd) != None:
|
||||
included = True
|
||||
break
|
||||
if excluded and not included:
|
||||
if len(fullcmd)>60:
|
||||
fullcmd = fullcmd[0:60] + ".."
|
||||
print "Skipping '%s'" % (fullcmd)
|
||||
continue
|
||||
|
||||
b = ["ccdash.py"]
|
||||
b.extend(a)
|
||||
a = b
|
||||
#print a
|
||||
try:
|
||||
rc = ccdash.main(a)
|
||||
except Exception, e:
|
||||
errmsg = str(e)
|
||||
print "**** Error: ccdash got exception %s ****" % errmsg
|
||||
rc = -1
|
||||
except:
|
||||
print "**** Error: ccdash got unknown exception ****"
|
||||
rc = -1
|
||||
|
||||
if rc!=0 and a[1] in mandatory_op:
|
||||
print "Stopping because of error.."
|
||||
break
|
||||
counter = counter + 1
|
||||
self.post_action()
|
||||
|
||||
|
||||
#
|
||||
# GNU test configurator
|
||||
#
|
||||
class GNUTestBuilder(TestBuilder):
|
||||
"""\
|
||||
This class creates list of tests suitable for GNU targets.
|
||||
|
||||
"""
|
||||
def __init__(self, config, build_config_name="", user_mak="", \
|
||||
config_site="", cross_compile="", exclude=[], not_exclude=[]):
|
||||
"""\
|
||||
Parameters:
|
||||
config - BaseConfig instance
|
||||
build_config_name - Optional name to be added as suffix to the build
|
||||
name. Sample: "min-size", "O4", "TLS", etc.
|
||||
user_mak - Contents to be put on user.mak
|
||||
config_site - Contents to be put on config_site.h
|
||||
cross_compile - Optional cross-compile prefix. Must include the
|
||||
trailing dash, e.g. "arm-unknown-linux-"
|
||||
exclude - List of regular expression patterns for tests
|
||||
that will be excluded from the run
|
||||
not_exclude - List of regular expression patterns for tests
|
||||
that will be run regardless of whether they
|
||||
match the excluded pattern.
|
||||
|
||||
"""
|
||||
TestBuilder.__init__(self, config, build_config_name=build_config_name,
|
||||
user_mak=user_mak, config_site=config_site,
|
||||
exclude=exclude, not_exclude=not_exclude)
|
||||
self.cross_compile = cross_compile
|
||||
if self.cross_compile and self.cross_compile[-1] != '-':
|
||||
self.cross_compile.append("-")
|
||||
|
||||
def build_tests(self):
|
||||
if self.cross_compile:
|
||||
suffix = "-" + self.cross_compile[0:-1]
|
||||
build_name = self.cross_compile + \
|
||||
gcc_version(self.cross_compile + "gcc")
|
||||
else:
|
||||
proc = subprocess.Popen("sh "+self.config.base_dir+"/config.guess",
|
||||
shell=True, stdout=subprocess.PIPE)
|
||||
plat = proc.stdout.readline().rstrip(" \r\n")
|
||||
build_name = plat + "-"+gcc_version(self.cross_compile + "gcc")
|
||||
suffix = "-" + plat
|
||||
|
||||
if self.build_config_name:
|
||||
build_name = build_name + "-" + self.build_config_name
|
||||
cmds = []
|
||||
cmds.extend(update_ops)
|
||||
cmds.append(Operation(Operation.CONFIGURE, "sh ./configure"))
|
||||
if sys.platform=="win32":
|
||||
# Don't build python module on Mingw
|
||||
cmds.append(Operation(Operation.BUILD,
|
||||
"sh -c 'make distclean && make dep && make'"))
|
||||
else:
|
||||
cmds.append(Operation(Operation.BUILD,
|
||||
"sh -c 'make distclean && make dep && make" + \
|
||||
" && cd pjsip-apps/src/python && " + \
|
||||
"python setup.py clean build'"))
|
||||
|
||||
cmds.extend(std_test_ops)
|
||||
cmds.extend(build_pjsua_test_ops())
|
||||
self.ccdash_args = []
|
||||
for c in cmds:
|
||||
c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
|
||||
args = c.encode(self.config.base_dir)
|
||||
args.extend(["-U", self.config.url,
|
||||
"-S", self.config.site,
|
||||
"-T", self.stamp(),
|
||||
"-B", build_name,
|
||||
"-G", self.config.group])
|
||||
args.extend(self.config.options)
|
||||
self.ccdash_args.append(args)
|
||||
|
||||
#
|
||||
# MSVC test configurator
|
||||
#
|
||||
class MSVCTestBuilder(TestBuilder):
|
||||
"""\
|
||||
This class creates list of tests suitable for Visual Studio builds.
|
||||
You need to set the MSVC environment variables (typically by calling
|
||||
vcvars32.bat) prior to running this class.
|
||||
|
||||
"""
|
||||
def __init__(self, config, target="Release|Win32", build_config_name="",
|
||||
config_site="", exclude=[], not_exclude=[]):
|
||||
"""\
|
||||
Parameters:
|
||||
config - BaseConfig instance
|
||||
target - Visual Studio build configuration to build.
|
||||
Sample: "Debug|Win32", "Release|Win32".
|
||||
build_config_name - Optional name to be added as suffix to the build
|
||||
name. Sample: "Debug", "Release", "IPv6", etc.
|
||||
config_site - Contents to be put on config_site.h
|
||||
exclude - List of regular expression patterns for tests
|
||||
that will be excluded from the run
|
||||
not_exclude - List of regular expression patterns for tests
|
||||
that will be run regardless of whether they
|
||||
match the excluded pattern.
|
||||
|
||||
"""
|
||||
TestBuilder.__init__(self, config, build_config_name=build_config_name,
|
||||
config_site=config_site, exclude=exclude,
|
||||
not_exclude=not_exclude)
|
||||
self.target = target.lower()
|
||||
|
||||
def build_tests(self):
|
||||
|
||||
(vsbuild,sys) = self.target.split("|",2)
|
||||
|
||||
build_name = sys + "-" + vs_get_version() + "-" + vsbuild
|
||||
|
||||
if self.build_config_name:
|
||||
build_name = build_name + "-" + self.build_config_name
|
||||
|
||||
vccmd = "vcbuild.exe /nologo /nohtmllog /nocolor /rebuild " + \
|
||||
"pjproject-vs8.sln " + " \"" + self.target + "\""
|
||||
|
||||
suffix = "-i386-win32-vc8-" + vsbuild
|
||||
pjsua = "pjsua_vc8"
|
||||
if vsbuild=="debug":
|
||||
pjsua = pjsua + "d"
|
||||
|
||||
cmds = []
|
||||
cmds.extend(update_ops)
|
||||
cmds.append(Operation(Operation.CONFIGURE, "CMD /C echo Nothing to do"))
|
||||
cmds.append(Operation(Operation.BUILD, vccmd))
|
||||
cmds.extend(std_test_ops)
|
||||
cmds.extend(build_pjsua_test_ops(pjsua))
|
||||
|
||||
self.ccdash_args = []
|
||||
for c in cmds:
|
||||
c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
|
||||
args = c.encode(self.config.base_dir)
|
||||
args.extend(["-U", self.config.url,
|
||||
"-S", self.config.site,
|
||||
"-T", self.stamp(),
|
||||
"-B", build_name,
|
||||
"-G", self.config.group])
|
||||
args.extend(self.config.options)
|
||||
self.ccdash_args.append(args)
|
||||
|
||||
|
||||
#
|
||||
# Symbian test configurator
|
||||
#
|
||||
class SymbianTestBuilder(TestBuilder):
|
||||
"""\
|
||||
This class creates list of tests suitable for Symbian builds. You need to
|
||||
set the command line build settings prior to running this class (typically
|
||||
that involves setting the EPOCROOT variable and current device).
|
||||
|
||||
"""
|
||||
def __init__(self, config, target="gcce urel", build_config_name="",
|
||||
config_site="", exclude=[], not_exclude=[]):
|
||||
"""\
|
||||
Parameters:
|
||||
config - BaseConfig instance
|
||||
target - Symbian target to build. Default is "gcce urel".
|
||||
build_config_name - Optional name to be added as suffix to the build
|
||||
name. Sample: "APS", "VAS", etc.
|
||||
config_site - Contents to be put on config_site.h
|
||||
exclude - List of regular expression patterns for tests
|
||||
that will be excluded from the run
|
||||
not_exclude - List of regular expression patterns for tests
|
||||
that will be run regardless of whether they
|
||||
match the excluded pattern.
|
||||
|
||||
"""
|
||||
TestBuilder.__init__(self, config, build_config_name=build_config_name,
|
||||
config_site=config_site, exclude=exclude,
|
||||
not_exclude=not_exclude)
|
||||
self.target = target.lower()
|
||||
|
||||
def build_tests(self):
|
||||
|
||||
# Check that EPOCROOT is set
|
||||
if not "EPOCROOT" in os.environ:
|
||||
print "Error: EPOCROOT environment variable is not set"
|
||||
sys.exit(1)
|
||||
epocroot = os.environ["EPOCROOT"]
|
||||
# EPOCROOT must have trailing backslash
|
||||
if epocroot[-1] != "\\":
|
||||
epocroot = epocroot + "\\"
|
||||
os.environ["EPOCROOT"] = epocroot
|
||||
sdk1 = epocroot.split("\\")[-2]
|
||||
|
||||
# Check that correct device is set
|
||||
proc = subprocess.Popen("devices", stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT, shell=True)
|
||||
sdk2 = ""
|
||||
while True:
|
||||
line = proc.stdout.readline()
|
||||
if line.find("- default") > 0:
|
||||
sdk2 = line.split(":",1)[0]
|
||||
break
|
||||
proc.wait()
|
||||
|
||||
if sdk1 != sdk2:
|
||||
print "Error: default SDK in device doesn't match EPOCROOT"
|
||||
print "Default device SDK =", sdk2
|
||||
print "EPOCROOT SDK =", sdk1
|
||||
sys.exit(1)
|
||||
|
||||
build_name = sdk2.replace("_", "-") + "-" + \
|
||||
self.target.replace(" ", "-")
|
||||
|
||||
if self.build_config_name:
|
||||
build_name = build_name + "-" + self.build_config_name
|
||||
|
||||
cmdline = "cmd /C \"cd build.symbian && bldmake bldfiles && abld build %s\"" % (self.target)
|
||||
|
||||
cmds = []
|
||||
cmds.extend(update_ops)
|
||||
cmds.append(Operation(Operation.CONFIGURE, "CMD /C echo Nothing to do"))
|
||||
cmds.extend([Operation(Operation.BUILD, cmdline)])
|
||||
|
||||
self.ccdash_args = []
|
||||
suffix = ""
|
||||
for c in cmds:
|
||||
c.cmdline = c.cmdline.replace("$SUFFIX", suffix)
|
||||
args = c.encode(self.config.base_dir)
|
||||
args.extend(["-U", self.config.url,
|
||||
"-S", self.config.site,
|
||||
"-T", self.stamp(),
|
||||
"-B", build_name,
|
||||
"-G", self.config.group])
|
||||
args.extend(self.config.options)
|
||||
self.ccdash_args.append(args)
|
||||
|
73
res/pjproject/tests/cdash/cfg_gnu.py
Normal file
73
res/pjproject/tests/cdash/cfg_gnu.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# cfg_gnu.py - GNU target configurator
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
import builder
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Each configurator must export this function
|
||||
def create_builder(args):
|
||||
usage = """\
|
||||
Usage:
|
||||
main.py cfg_gnu [-h|--help] [cfg_site]
|
||||
|
||||
Arguments:
|
||||
cfg_site: site configuration module. If not specified, "cfg_site"
|
||||
is implied
|
||||
-h, --help Show this help screen
|
||||
|
||||
"""
|
||||
# (optional) args format:
|
||||
# site configuration module. If not specified, "cfg_site" is implied
|
||||
|
||||
cfg_site = "cfg_site"
|
||||
|
||||
for arg in args:
|
||||
if arg=="-h" or arg=="--help":
|
||||
print usage
|
||||
sys.exit(0)
|
||||
elif arg[0]=="-":
|
||||
print usage
|
||||
sys.exit(1)
|
||||
else:
|
||||
cfg_site = arg
|
||||
|
||||
if os.access(cfg_site+".py", os.F_OK) == False:
|
||||
print "Error: file '%s.py' doesn't exist." % (cfg_site)
|
||||
sys.exit(1)
|
||||
|
||||
cfg_site = __import__(cfg_site)
|
||||
test_cfg = builder.BaseConfig(cfg_site.BASE_DIR, \
|
||||
cfg_site.URL, \
|
||||
cfg_site.SITE_NAME, \
|
||||
cfg_site.GROUP, \
|
||||
cfg_site.OPTIONS)
|
||||
|
||||
config_site = "#define PJ_TODO(x)\n" + cfg_site.CONFIG_SITE
|
||||
user_mak = "export CFLAGS+=-Wall\n" + cfg_site.USER_MAK
|
||||
|
||||
builders = [
|
||||
builder.GNUTestBuilder(test_cfg, build_config_name="default",
|
||||
user_mak=user_mak,
|
||||
config_site=config_site,
|
||||
exclude=cfg_site.EXCLUDE,
|
||||
not_exclude=cfg_site.NOT_EXCLUDE)
|
||||
]
|
||||
|
||||
return builders
|
82
res/pjproject/tests/cdash/cfg_msvc.py
Normal file
82
res/pjproject/tests/cdash/cfg_msvc.py
Normal file
@@ -0,0 +1,82 @@
|
||||
#
|
||||
# cfg_msvc.py - MSVC/Visual Studio target configurator
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
import builder
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Each configurator must export this function
|
||||
def create_builder(args):
|
||||
usage = """\
|
||||
Usage:
|
||||
main.py cfg_msvc [-h|--help] [-t|--target TARGET] [cfg_site]
|
||||
|
||||
Arguments:
|
||||
cfg_site: site configuration module. If not specified, "cfg_site"
|
||||
is implied
|
||||
-t,--target TARGET: Visual Studio build configuration to build. Default is
|
||||
"Release|Win32". Sample values: "Debug|Win32"
|
||||
-h, --help Show this help screen
|
||||
|
||||
"""
|
||||
|
||||
cfg_site = "cfg_site"
|
||||
target = "Release|Win32"
|
||||
in_option = ""
|
||||
|
||||
for arg in args:
|
||||
if in_option=="-t":
|
||||
target = arg
|
||||
in_option = ""
|
||||
elif arg=="--target" or arg=="-t":
|
||||
in_option = "-t"
|
||||
elif arg=="-h" or arg=="--help":
|
||||
print usage
|
||||
sys.exit(0)
|
||||
elif arg[0]=="-":
|
||||
print usage
|
||||
sys.exit(1)
|
||||
else:
|
||||
cfg_site = arg
|
||||
|
||||
if os.access(cfg_site+".py", os.F_OK) == False:
|
||||
print "Error: file '%s.py' doesn't exist." % (cfg_site)
|
||||
sys.exit(1)
|
||||
|
||||
cfg_site = __import__(cfg_site)
|
||||
test_cfg = builder.BaseConfig(cfg_site.BASE_DIR, \
|
||||
cfg_site.URL, \
|
||||
cfg_site.SITE_NAME, \
|
||||
cfg_site.GROUP, \
|
||||
cfg_site.OPTIONS)
|
||||
|
||||
config_site = "#define PJ_TODO(x)\n" + cfg_site.CONFIG_SITE
|
||||
user_mak = cfg_site.USER_MAK
|
||||
|
||||
builders = [
|
||||
builder.MSVCTestBuilder(test_cfg,
|
||||
target=target,
|
||||
build_config_name="default",
|
||||
config_site=config_site,
|
||||
exclude=cfg_site.EXCLUDE,
|
||||
not_exclude=cfg_site.NOT_EXCLUDE)
|
||||
]
|
||||
|
||||
return builders
|
||||
|
50
res/pjproject/tests/cdash/cfg_site_sample.py
Normal file
50
res/pjproject/tests/cdash/cfg_site_sample.py
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# cfg_site_sample.py - Sample site configuration
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
import builder
|
||||
|
||||
# Your site name
|
||||
SITE_NAME="Newham3"
|
||||
|
||||
# The URL where tests will be submitted to
|
||||
URL = "http://192.168.0.2/dash/submit.php?project=PJSIP"
|
||||
|
||||
# Test group
|
||||
GROUP = "Experimental"
|
||||
|
||||
# PJSIP base directory
|
||||
BASE_DIR = "/root/project/pjproject"
|
||||
|
||||
# List of additional ccdash options
|
||||
#OPTIONS = ["-o", "out.xml", "-y"]
|
||||
OPTIONS = []
|
||||
|
||||
# What's the content of config_site.h
|
||||
CONFIG_SITE = ""
|
||||
|
||||
# What's the content of user.mak
|
||||
USER_MAK = ""
|
||||
|
||||
# List of regular expression of test patterns to be excluded
|
||||
EXCLUDE = []
|
||||
|
||||
# List of regular expression of test patterns to be included (even
|
||||
# if they match EXCLUDE patterns)
|
||||
NOT_EXCLUDE = []
|
||||
#"configure", "update", "build.*make", "build", "run.py mod_run.*100_simple"]
|
86
res/pjproject/tests/cdash/cfg_symbian.py
Normal file
86
res/pjproject/tests/cdash/cfg_symbian.py
Normal file
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# cfg_symbian.py - Symbian target configurator
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
import builder
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Each configurator must export this function
|
||||
def create_builder(args):
|
||||
usage = """\
|
||||
Usage:
|
||||
main.py cfg_symbian [-h|--help] [-t|--target TARGET] [cfg_site]
|
||||
|
||||
Arguments:
|
||||
cfg_site: site configuration module. If not specified, "cfg_site"
|
||||
is implied
|
||||
-t,--target TARGET: Symbian target to build. Default is "gcce urel".
|
||||
Other values:
|
||||
"winscw udeb", "gcce udeb", etc.
|
||||
-h, --help Show this help screen
|
||||
"""
|
||||
|
||||
cfg_site = "cfg_site"
|
||||
target = "gcce urel"
|
||||
in_option = ""
|
||||
|
||||
for arg in args:
|
||||
if in_option=="-t":
|
||||
target = arg
|
||||
in_option = ""
|
||||
elif arg=="--target" or arg=="-t":
|
||||
in_option = "-t"
|
||||
elif arg=="--help" or arg=="-h":
|
||||
print usage
|
||||
sys.exit(0)
|
||||
elif arg[0]=="-":
|
||||
print usage
|
||||
sys.exit(1)
|
||||
else:
|
||||
cfg_site = arg
|
||||
|
||||
if os.access(cfg_site+".py", os.F_OK) == False:
|
||||
print "Error: file '%s.py' doesn't exist." % (cfg_site)
|
||||
sys.exit(1)
|
||||
|
||||
cfg_site = __import__(cfg_site)
|
||||
test_cfg = builder.BaseConfig(cfg_site.BASE_DIR, \
|
||||
cfg_site.URL, \
|
||||
cfg_site.SITE_NAME, \
|
||||
cfg_site.GROUP, \
|
||||
cfg_site.OPTIONS)
|
||||
config_site1 = """\
|
||||
#define PJ_TODO(x)
|
||||
#include <pj/config_site_sample.h>
|
||||
|
||||
"""
|
||||
|
||||
config_Site = config_site1 + cfg_site.CONFIG_SITE
|
||||
|
||||
builders = [
|
||||
builder.SymbianTestBuilder(test_cfg,
|
||||
target=target,
|
||||
build_config_name="default",
|
||||
config_site=config_site1,
|
||||
exclude=cfg_site.EXCLUDE,
|
||||
not_exclude=cfg_site.NOT_EXCLUDE)
|
||||
]
|
||||
|
||||
return builders
|
||||
|
1
res/pjproject/tests/cdash/inc_test.py
Normal file
1
res/pjproject/tests/cdash/inc_test.py
Normal file
@@ -0,0 +1 @@
|
||||
|
42
res/pjproject/tests/cdash/main.py
Normal file
42
res/pjproject/tests/cdash/main.py
Normal file
@@ -0,0 +1,42 @@
|
||||
#!/bin/env python
|
||||
|
||||
#
|
||||
# main.py - main entry for PJSIP's CDash tests
|
||||
#
|
||||
# Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
import sys
|
||||
|
||||
if len(sys.argv)==1:
|
||||
print "Usage: main.py cfg_file [cfg_site]"
|
||||
print "Example:"
|
||||
print " main.py cfg_gnu"
|
||||
print " main.py cfg_gnu custom_cfg_site"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
args = []
|
||||
args.extend(sys.argv)
|
||||
args.remove(args[1])
|
||||
args.remove(args[0])
|
||||
|
||||
cfg_file = __import__(sys.argv[1])
|
||||
builders = cfg_file.create_builder(args)
|
||||
|
||||
for builder in builders:
|
||||
builder.execute()
|
44
res/pjproject/tests/cdash/starttest_sample.bat
Normal file
44
res/pjproject/tests/cdash/starttest_sample.bat
Normal file
@@ -0,0 +1,44 @@
|
||||
@echo off
|
||||
|
||||
rem ***
|
||||
rem ************** VS 2005 **************
|
||||
rem ***
|
||||
set OLD_PATH=%PATH%
|
||||
set OLD_INCLUDE=%INCLUDE%
|
||||
set OLD_LIB=%LIB%
|
||||
set OLD_LIBPATH=%LIBPATH%
|
||||
|
||||
call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat" x86
|
||||
python main.py cfg_msvc -t "Debug|Win32"
|
||||
python main.py cfg_msvc -t "Release|Win32"
|
||||
|
||||
set PATH=%OLD_PATH%
|
||||
set INCLUDE=%OLD_INCLUDE%
|
||||
set LIB=%OLD_LIB%
|
||||
set LIBPATH=%OLD_LIBPATH%
|
||||
|
||||
|
||||
rem ***
|
||||
rem ************** S60 3rd FP1 **************
|
||||
rem ***
|
||||
set EPOCROOT=\symbian\9.2\S60_3rd_FP1\
|
||||
devices -setdefault @S60_3rd_FP1:com.nokia.s60
|
||||
python main.py cfg_symbian -t "winscw udeb"
|
||||
python main.py cfg_symbian -t "gcce udeb"
|
||||
python main.py cfg_symbian -t "gcce urel"
|
||||
|
||||
|
||||
rem ***
|
||||
rem ************** Mingw **************
|
||||
rem ***
|
||||
set MSYSTEM=MINGW32
|
||||
set DISPLAY=
|
||||
C:\msys\1.0\bin\sh -c "python main.py cfg_gnu"
|
||||
|
||||
|
||||
rem ***
|
||||
rem ************** Linux **************
|
||||
rem ***
|
||||
set PATH=%PATH%;c:\msys\1.0\bin
|
||||
set HOME=C:\msys\1.0\home\Administrator
|
||||
C:\mingw\bin\ssh test@192.168.0.12 "cd project/pjproject/tests/cdash && python main.py cfg_gnu"
|
65
res/pjproject/tests/pjsua/README.TXT
Normal file
65
res/pjproject/tests/pjsua/README.TXT
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
PJSUA TEST FRAMEWORK
|
||||
=========================
|
||||
|
||||
0. What is this
|
||||
---------------
|
||||
This is the automated testing scripts for pjsua. It can do many things (just
|
||||
don't ask it to write good documentation :) ).
|
||||
|
||||
|
||||
1. Requirements
|
||||
---------------
|
||||
To run the tests you need:
|
||||
- Python (tested with Python 2.5.2)
|
||||
- pjsua application, built and placed in pjsip-apps/bin directory
|
||||
- the pjsua must be built with:
|
||||
- SRTP enabled (the default)
|
||||
|
||||
|
||||
2. Using
|
||||
--------
|
||||
To run all the tests:
|
||||
$ python [OPTIONS] runall.py
|
||||
|
||||
To run individual test:
|
||||
$ python [OPTIONS] run.py MODULE CONFIG
|
||||
|
||||
Where options:
|
||||
-e EXE use EXE as pjsua executable
|
||||
-n use null audio
|
||||
-r TEST (for runall.py only) resume test at TEST
|
||||
|
||||
|
||||
For each individual tests, the run.py is the main entry for the test. It
|
||||
imports the various inc_xxx.py files, and it will load the MODULE. The MODULE
|
||||
contains specific test flows, and we have few of them:
|
||||
|
||||
- mod_run.py:
|
||||
a simple test which just run pjsua with the configuration from CONFIG
|
||||
file and checks if pjsua can start properly.
|
||||
|
||||
- mod_call.py:
|
||||
call testing where it spawns two pjsua instances each with configura-
|
||||
tions as specified in CONFIG file, makes one pjsua call the other, and
|
||||
checks if the call can be established.
|
||||
|
||||
- mod_pres.py:
|
||||
presence testing
|
||||
|
||||
- mod_sendto.py:
|
||||
Simple UAC to send arbitrary SIP message to pjsua. Good to test
|
||||
various incoming INVITE scenarios
|
||||
|
||||
- mod_media_playrec.py:
|
||||
Mainly for resampling quality testing
|
||||
|
||||
- mod_pesq.py
|
||||
Measure call quality of various call settings with PESQ, for people
|
||||
who have PESQ tool and license
|
||||
|
||||
Example:
|
||||
$ python run.py mod_run.py scripts-run/100_simple.py
|
||||
$ python run.py mod_call.py scripts-call/100_simple.py
|
||||
|
||||
|
4
res/pjproject/tests/pjsua/config_site.py
Normal file
4
res/pjproject/tests/pjsua/config_site.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# $Id$
|
||||
|
||||
# Specify if host has sound device, or test should be performed using sound device
|
||||
HAS_SND_DEV = 0
|
107
res/pjproject/tests/pjsua/inc_cfg.py
Normal file
107
res/pjproject/tests/pjsua/inc_cfg.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# $Id$
|
||||
import random
|
||||
import config_site
|
||||
|
||||
DEFAULT_ECHO = True
|
||||
DEFAULT_TRACE = True
|
||||
DEFAULT_START_SIP_PORT = 50000
|
||||
|
||||
# Shared vars
|
||||
ARGS = [] # arguments containing script module & config
|
||||
HAS_SND_DEV = config_site.HAS_SND_DEV
|
||||
|
||||
# Individual pjsua instance configuration class
|
||||
class InstanceParam:
|
||||
# Name to identify this pjsua instance (e.g. "caller", "callee", etc.)
|
||||
name = ""
|
||||
# pjsua command line arguments, concatenated in string
|
||||
arg = ""
|
||||
# Specify whether pjsua output should be echoed to stdout
|
||||
echo_enabled = DEFAULT_ECHO
|
||||
# Enable/disable test tracing
|
||||
trace_enabled = DEFAULT_TRACE
|
||||
# SIP URI to send request to this instance
|
||||
uri = ""
|
||||
# SIP port number, zero to automatically assign
|
||||
sip_port = 0
|
||||
# Does this have registration? If yes then the test function will
|
||||
# wait until the UA is registered before doing anything else
|
||||
have_reg = False
|
||||
# Does this have PUBLISH?
|
||||
have_publish = False
|
||||
# Enable stdout buffer?
|
||||
enable_buffer = False
|
||||
def __init__( self,
|
||||
name, # Instance name
|
||||
arg, # Cmd-line arguments
|
||||
uri="", # URI
|
||||
uri_param="", # Additional URI param
|
||||
sip_port=0, # SIP port
|
||||
have_reg=False, # Have registration?
|
||||
have_publish=False, # Have publish?
|
||||
echo_enabled=DEFAULT_ECHO,
|
||||
trace_enabled=DEFAULT_TRACE,
|
||||
enable_buffer = False):
|
||||
# Instance name
|
||||
self.name = name
|
||||
# Give random sip_port if it's not specified
|
||||
if sip_port==0:
|
||||
self.sip_port = random.randint(DEFAULT_START_SIP_PORT, 65534)
|
||||
else:
|
||||
self.sip_port = sip_port
|
||||
# Autogenerate URI if it's empty.
|
||||
self.uri = uri
|
||||
if self.uri=="":
|
||||
self.uri = "sip:pjsip@127.0.0.1:" + str(self.sip_port)
|
||||
# Add uri_param to the URI
|
||||
self.uri = self.uri + uri_param
|
||||
# Add bracket to the URI
|
||||
if self.uri[0] != "<":
|
||||
self.uri = "<" + self.uri + ">"
|
||||
# Add SIP local port to the argument
|
||||
self.arg = arg + " --local-port=" + str(self.sip_port)
|
||||
self.have_reg = have_reg
|
||||
self.have_publish = have_publish
|
||||
if have_publish and have_reg and not ("--publish" in self.arg):
|
||||
self.arg = self.arg + " --publish"
|
||||
self.echo_enabled = echo_enabled
|
||||
self.trace_enabled = trace_enabled
|
||||
self.enable_buffer = enable_buffer
|
||||
|
||||
|
||||
############################################
|
||||
# Test parameter class
|
||||
class TestParam:
|
||||
title = ""
|
||||
# params is list containing InstanceParams objects
|
||||
inst_params = []
|
||||
# flag if this tes should be skipped
|
||||
skip = None
|
||||
# list of Expect instances, to be filled at run-time by
|
||||
# the test program
|
||||
process = []
|
||||
# the function for test body
|
||||
test_func = None
|
||||
post_func = None
|
||||
def __init__( self,
|
||||
title, # Test title
|
||||
inst_params, # InstanceParam's as list
|
||||
func=None,
|
||||
skip=False,
|
||||
post_func=None,
|
||||
need_stdout_buffer=False):
|
||||
self.title = title
|
||||
self.inst_params = inst_params
|
||||
self.skip = skip
|
||||
self.test_func = func
|
||||
self.post_func = post_func
|
||||
|
||||
|
||||
###################################
|
||||
# TestError exception
|
||||
class TestError:
|
||||
desc = ""
|
||||
def __init__(self, desc):
|
||||
self.desc = desc
|
||||
|
||||
|
62
res/pjproject/tests/pjsua/inc_const.py
Normal file
62
res/pjproject/tests/pjsua/inc_const.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# $Id$
|
||||
# Useful constants
|
||||
|
||||
|
||||
##########################
|
||||
# MENU OUTPUT
|
||||
#
|
||||
|
||||
|
||||
##########################
|
||||
# EVENTS
|
||||
#
|
||||
|
||||
# Text to expect when there is incoming call
|
||||
EVENT_INCOMING_CALL = "Press .* answer"
|
||||
|
||||
|
||||
##########################
|
||||
# CALL STATES
|
||||
#
|
||||
|
||||
# Call state is CALLING
|
||||
STATE_CALLING = "state.*CALLING"
|
||||
# Call state is CONFIRMED
|
||||
STATE_CONFIRMED = "state.*CONFIRMED"
|
||||
# Call state is DISCONNECTED
|
||||
STATE_DISCONNECTED = "Call .* DISCONNECTED"
|
||||
|
||||
# Media call is put on-hold
|
||||
MEDIA_HOLD = "Call [0-9]+ media [0-9]+ .*, status is .* hold"
|
||||
# Media call is active
|
||||
MEDIA_ACTIVE = "Call [0-9]+ media [0-9]+ .*, status is Active"
|
||||
#MEDIA_ACTIVE = "Media for call [0-9]+ is active"
|
||||
# RX_DTMF
|
||||
RX_DTMF = "Incoming DTMF on call [0-9]+: "
|
||||
|
||||
##########################
|
||||
# MEDIA
|
||||
#
|
||||
|
||||
# Connecting/disconnecting ports
|
||||
MEDIA_CONN_PORT_SUCCESS = "Port \d+ \(.+\) transmitting to port"
|
||||
MEDIA_DISCONN_PORT_SUCCESS = "Port \d+ \(.+\) stop transmitting to port"
|
||||
|
||||
# Filename to play / record
|
||||
MEDIA_PLAY_FILE = "--play-file\s+(\S+)"
|
||||
MEDIA_REC_FILE = "--rec-file\s+(\S+)"
|
||||
|
||||
##########################
|
||||
# MISC
|
||||
#
|
||||
|
||||
# The command prompt
|
||||
PROMPT = ">>>"
|
||||
# When pjsua has been destroyed
|
||||
DESTROYED = "PJSUA destroyed"
|
||||
# Assertion failure
|
||||
ASSERT = "Assertion failed"
|
||||
# Stdout refresh text
|
||||
STDOUT_REFRESH = "XXSTDOUT_REFRESHXX"
|
||||
|
||||
|
38
res/pjproject/tests/pjsua/inc_sdp.py
Normal file
38
res/pjproject/tests/pjsua/inc_sdp.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# $Id$
|
||||
|
||||
# SDP template
|
||||
sdp_templ = \
|
||||
"""v=0\r
|
||||
o=- 1 1 $NET_TYPE $ADDR_TYPE $LOCAL_IP\r
|
||||
s=pjmedia\r
|
||||
t=0 0\r
|
||||
$SDP_LINES"""
|
||||
|
||||
sdp_media_templ = \
|
||||
"""m=$MEDIA_TYPE $PORT $TRANSPORT 0\r
|
||||
c=$NET_TYPE $ADDR_TYPE $LOCAL_IP\r
|
||||
$SDP_LINES"""
|
||||
|
||||
# Create SDP session
|
||||
def session(local_ip="127.0.0.1", extra_lines="", net_type="IN", addr_type="IP4"):
|
||||
sdp = sdp_templ
|
||||
sdp = sdp.replace("$NET_TYPE", net_type)
|
||||
sdp = sdp.replace("$ADDR_TYPE", addr_type)
|
||||
sdp = sdp.replace("$LOCAL_IP", local_ip)
|
||||
sdp = sdp.replace("$SDP_LINES", extra_lines)
|
||||
return sdp
|
||||
|
||||
# Create basic SDP media
|
||||
def media(media_type="audio", local_port=4000, local_ip="127.0.0.1", extra_lines="",
|
||||
net_type = "IN", addr_type="IP4", transport="RTP/AVP"):
|
||||
sdp = sdp_media_templ
|
||||
sdp = sdp.replace("$MEDIA_TYPE", media_type)
|
||||
sdp = sdp.replace("$LOCAL_IP", local_ip)
|
||||
sdp = sdp.replace("$PORT", str(local_port))
|
||||
sdp = sdp.replace("$NET_TYPE", net_type)
|
||||
sdp = sdp.replace("$ADDR_TYPE", addr_type)
|
||||
sdp = sdp.replace("$TRANSPORT", transport)
|
||||
sdp = sdp.replace("$SDP_LINES", extra_lines)
|
||||
return sdp
|
||||
|
||||
|
343
res/pjproject/tests/pjsua/inc_sip.py
Normal file
343
res/pjproject/tests/pjsua/inc_sip.py
Normal file
@@ -0,0 +1,343 @@
|
||||
# $Id$
|
||||
#
|
||||
from socket import *
|
||||
import re
|
||||
import random
|
||||
import time
|
||||
import sys
|
||||
import inc_cfg as cfg
|
||||
from select import *
|
||||
|
||||
# SIP request template
|
||||
req_templ = \
|
||||
"""$METHOD $TARGET_URI SIP/2.0\r
|
||||
Via: SIP/2.0/UDP $LOCAL_IP:$LOCAL_PORT;rport;branch=z9hG4bK$BRANCH\r
|
||||
Max-Forwards: 70\r
|
||||
From: <sip:caller@pjsip.org>$FROM_TAG\r
|
||||
To: <$TARGET_URI>$TO_TAG\r
|
||||
Contact: <sip:$LOCAL_IP:$LOCAL_PORT;transport=udp>\r
|
||||
Call-ID: $CALL_ID@pjsip.org\r
|
||||
CSeq: $CSEQ $METHOD\r
|
||||
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, REFER\r
|
||||
Supported: replaces, 100rel, norefersub\r
|
||||
User-Agent: pjsip.org Python tester\r
|
||||
Content-Length: $CONTENT_LENGTH\r
|
||||
$SIP_HEADERS"""
|
||||
|
||||
|
||||
def is_request(msg):
|
||||
return msg.split(" ", 1)[0] != "SIP/2.0"
|
||||
|
||||
def is_response(msg):
|
||||
return msg.split(" ", 1)[0] == "SIP/2.0"
|
||||
|
||||
def get_code(msg):
|
||||
if msg=="":
|
||||
return 0
|
||||
return int(msg.split(" ", 2)[1])
|
||||
|
||||
def get_tag(msg, hdr="To"):
|
||||
pat = "^" + hdr + ":.*"
|
||||
result = re.search(pat, msg, re.M | re.I)
|
||||
if result==None:
|
||||
return ""
|
||||
line = result.group()
|
||||
#print "line=", line
|
||||
tags = line.split(";tag=")
|
||||
if len(tags)>1:
|
||||
return tags[1]
|
||||
return ""
|
||||
#return re.split("[;& ]", s)
|
||||
|
||||
def get_header(msg, hname):
|
||||
headers = msg.splitlines()
|
||||
for hdr in headers:
|
||||
hfields = hdr.split(": ", 2)
|
||||
if hfields[0]==hname:
|
||||
return hfields[1]
|
||||
return None
|
||||
|
||||
class Dialog:
|
||||
sock = None
|
||||
dst_addr = ""
|
||||
dst_port = 5060
|
||||
local_ip = ""
|
||||
local_port = 0
|
||||
tcp = False
|
||||
call_id = str(random.random())
|
||||
cseq = 0
|
||||
local_tag = ";tag=" + str(random.random())
|
||||
rem_tag = ""
|
||||
last_resp_code = 0
|
||||
inv_branch = ""
|
||||
trace_enabled = True
|
||||
last_request = ""
|
||||
def __init__(self, dst_addr, dst_port=5060, tcp=False, trace=True, local_port=0):
|
||||
self.dst_addr = dst_addr
|
||||
self.dst_port = dst_port
|
||||
self.tcp = tcp
|
||||
self.trace_enabled = trace
|
||||
if tcp==True:
|
||||
self.sock = socket(AF_INET, SOCK_STREAM)
|
||||
self.sock.connect(dst_addr, dst_port)
|
||||
else:
|
||||
self.sock = socket(AF_INET, SOCK_DGRAM)
|
||||
self.sock.bind(("127.0.0.1", local_port))
|
||||
|
||||
self.local_ip, self.local_port = self.sock.getsockname()
|
||||
self.trace("Dialog socket bound to " + self.local_ip + ":" + str(self.local_port))
|
||||
|
||||
def trace(self, txt):
|
||||
if self.trace_enabled:
|
||||
print str(time.strftime("%H:%M:%S ")) + txt
|
||||
|
||||
def update_fields(self, msg):
|
||||
if self.tcp:
|
||||
transport_param = ";transport=tcp"
|
||||
else:
|
||||
transport_param = ""
|
||||
msg = msg.replace("$TARGET_URI", "sip:"+self.dst_addr+":"+str(self.dst_port) + transport_param)
|
||||
msg = msg.replace("$LOCAL_IP", self.local_ip)
|
||||
msg = msg.replace("$LOCAL_PORT", str(self.local_port))
|
||||
msg = msg.replace("$FROM_TAG", self.local_tag)
|
||||
msg = msg.replace("$TO_TAG", self.rem_tag)
|
||||
msg = msg.replace("$CALL_ID", self.call_id)
|
||||
msg = msg.replace("$CSEQ", str(self.cseq))
|
||||
branch=str(random.random())
|
||||
msg = msg.replace("$BRANCH", branch)
|
||||
return msg
|
||||
|
||||
def create_req(self, method, sdp, branch="", extra_headers="", body=""):
|
||||
if branch=="":
|
||||
self.cseq = self.cseq + 1
|
||||
msg = req_templ
|
||||
msg = msg.replace("$METHOD", method)
|
||||
msg = msg.replace("$SIP_HEADERS", extra_headers)
|
||||
if branch=="":
|
||||
branch=str(random.random())
|
||||
msg = msg.replace("$BRANCH", branch)
|
||||
if sdp!="":
|
||||
msg = msg.replace("$CONTENT_LENGTH", str(len(sdp)))
|
||||
msg = msg + "Content-Type: application/sdp\r\n"
|
||||
msg = msg + "\r\n"
|
||||
msg = msg + sdp
|
||||
elif body!="":
|
||||
msg = msg.replace("$CONTENT_LENGTH", str(len(body)))
|
||||
msg = msg + "\r\n"
|
||||
msg = msg + body
|
||||
else:
|
||||
msg = msg.replace("$CONTENT_LENGTH", "0")
|
||||
return self.update_fields(msg)
|
||||
|
||||
def create_response(self, request, code, reason, to_tag=""):
|
||||
response = "SIP/2.0 " + str(code) + " " + reason + "\r\n"
|
||||
lines = request.splitlines()
|
||||
for line in lines:
|
||||
hdr = line.split(":", 1)[0]
|
||||
if hdr in ["Via", "From", "To", "CSeq", "Call-ID"]:
|
||||
if hdr=="To" and to_tag!="":
|
||||
line = line + ";tag=" + to_tag
|
||||
elif hdr=="Via":
|
||||
line = line + ";received=127.0.0.1"
|
||||
response = response + line + "\r\n"
|
||||
return response
|
||||
|
||||
def create_invite(self, sdp, extra_headers="", body=""):
|
||||
self.inv_branch = str(random.random())
|
||||
return self.create_req("INVITE", sdp, branch=self.inv_branch, extra_headers=extra_headers, body=body)
|
||||
|
||||
def create_ack(self, sdp="", extra_headers=""):
|
||||
return self.create_req("ACK", sdp, extra_headers=extra_headers, branch=self.inv_branch)
|
||||
|
||||
def create_bye(self, extra_headers=""):
|
||||
return self.create_req("BYE", "", extra_headers)
|
||||
|
||||
def send_msg(self, msg, dst_addr=None):
|
||||
if (is_request(msg)):
|
||||
self.last_request = msg.split(" ", 1)[0]
|
||||
if not dst_addr:
|
||||
dst_addr = (self.dst_addr, self.dst_port)
|
||||
self.trace("============== TX MSG to " + str(dst_addr) + " ============= \n" + msg)
|
||||
self.sock.sendto(msg, 0, dst_addr)
|
||||
|
||||
def wait_msg_from(self, timeout):
|
||||
endtime = time.time() + timeout
|
||||
msg = ""
|
||||
src_addr = None
|
||||
while time.time() < endtime:
|
||||
readset = select([self.sock], [], [], 1)
|
||||
if len(readset[0]) < 1 or not self.sock in readset[0]:
|
||||
if len(readset[0]) < 1:
|
||||
print "select() timeout (will wait for " + str(int(endtime - time.time())) + "more secs)"
|
||||
elif not self.sock in readset[0]:
|
||||
print "select() alien socket"
|
||||
else:
|
||||
print "select other error"
|
||||
continue
|
||||
try:
|
||||
msg, src_addr = self.sock.recvfrom(4096)
|
||||
break
|
||||
except:
|
||||
print "recv() exception: ", sys.exc_info()[0]
|
||||
continue
|
||||
|
||||
if msg=="":
|
||||
return "", None
|
||||
if self.last_request=="INVITE" and self.rem_tag=="":
|
||||
self.rem_tag = get_tag(msg, "To")
|
||||
self.rem_tag = self.rem_tag.rstrip("\r\n;")
|
||||
if self.rem_tag != "":
|
||||
self.rem_tag = ";tag=" + self.rem_tag
|
||||
self.trace("=== rem_tag:" + self.rem_tag)
|
||||
self.trace("=========== RX MSG from " + str(src_addr) + " ===========\n" + msg)
|
||||
return (msg, src_addr)
|
||||
|
||||
def wait_msg(self, timeout):
|
||||
return self.wait_msg_from(timeout)[0]
|
||||
|
||||
# Send request and wait for final response
|
||||
def send_request_wait(self, msg, timeout):
|
||||
t1 = 1.0
|
||||
endtime = time.time() + timeout
|
||||
resp = ""
|
||||
code = 0
|
||||
for i in range(0,5):
|
||||
self.send_msg(msg)
|
||||
resp = self.wait_msg(t1)
|
||||
if resp!="" and is_response(resp):
|
||||
code = get_code(resp)
|
||||
break
|
||||
last_resp = resp
|
||||
while code < 200 and time.time() < endtime:
|
||||
resp = self.wait_msg(endtime - time.time())
|
||||
if resp != "" and is_response(resp):
|
||||
code = get_code(resp)
|
||||
last_resp = resp
|
||||
elif resp=="":
|
||||
break
|
||||
return last_resp
|
||||
|
||||
def hangup(self, last_code=0):
|
||||
self.trace("====== hangup =====")
|
||||
if last_code!=0:
|
||||
self.last_resp_code = last_code
|
||||
if self.last_resp_code>0 and self.last_resp_code<200:
|
||||
msg = self.create_req("CANCEL", "", branch=self.inv_branch, extra_headers="")
|
||||
self.send_request_wait(msg, 5)
|
||||
msg = self.create_ack()
|
||||
self.send_msg(msg)
|
||||
elif self.last_resp_code>=200 and self.last_resp_code<300:
|
||||
msg = self.create_ack()
|
||||
self.send_msg(msg)
|
||||
msg = self.create_bye()
|
||||
self.send_request_wait(msg, 5)
|
||||
else:
|
||||
msg = self.create_ack()
|
||||
self.send_msg(msg)
|
||||
|
||||
|
||||
class SendtoCfg:
|
||||
# Test name
|
||||
name = ""
|
||||
# pjsua InstanceParam
|
||||
inst_param = None
|
||||
# Complete INVITE message. If this is not empty, then this
|
||||
# message will be sent instead and the "sdp" and "extra_headers"
|
||||
# settings will be ignored.
|
||||
complete_msg = ""
|
||||
# Initial SDP
|
||||
sdp = ""
|
||||
# Extra headers to add to request
|
||||
extra_headers = ""
|
||||
# Expected code
|
||||
resp_code = 0
|
||||
# Use TCP?
|
||||
use_tcp = False
|
||||
# List of RE patterns that must exist in response
|
||||
resp_include = []
|
||||
# List of RE patterns that must NOT exist in response
|
||||
resp_exclude = []
|
||||
# Full (non-SDP) body
|
||||
body = ""
|
||||
# Constructor
|
||||
def __init__(self, name, pjsua_args, sdp, resp_code,
|
||||
resp_inc=[], resp_exc=[], use_tcp=False,
|
||||
extra_headers="", body="", complete_msg="",
|
||||
enable_buffer = False):
|
||||
self.complete_msg = complete_msg
|
||||
self.sdp = sdp
|
||||
self.resp_code = resp_code
|
||||
self.resp_include = resp_inc
|
||||
self.resp_exclude = resp_exc
|
||||
self.use_tcp = use_tcp
|
||||
self.extra_headers = extra_headers
|
||||
self.body = body
|
||||
self.inst_param = cfg.InstanceParam("pjsua", pjsua_args)
|
||||
self.inst_param.enable_buffer = enable_buffer
|
||||
|
||||
|
||||
class RecvfromTransaction:
|
||||
# The test title for this transaction
|
||||
title = ""
|
||||
# Optinal list of pjsua command and optional expect patterns
|
||||
# to be invoked to make pjsua send a request
|
||||
# Sample:
|
||||
# (to make call and wait for INVITE to be sent)
|
||||
# cmds = [ ["m"], ["sip:127.0.0.1", "INVITE sip:"] ]
|
||||
cmds = []
|
||||
# Check if the CSeq must be greater than last Cseq?
|
||||
check_cseq = True
|
||||
# List of RE patterns that must exists in incoming request
|
||||
include = []
|
||||
# List of RE patterns that MUST NOT exist in incoming request
|
||||
exclude = []
|
||||
# Response code to send
|
||||
resp_code = 0
|
||||
# Additional list of headers to be sent on the response
|
||||
# Note: no need to add CRLF on the header
|
||||
resp_hdr = []
|
||||
# Message body. This should include the Content-Type header too.
|
||||
# Sample:
|
||||
# body = """Content-Type: application/sdp\r\n
|
||||
# \r\n
|
||||
# v=0\r\n
|
||||
# ...
|
||||
# """
|
||||
body = None
|
||||
# Pattern to be expected on pjsua when receiving the response
|
||||
expect = ""
|
||||
|
||||
def __init__(self, title, resp_code, check_cseq=True,
|
||||
include=[], exclude=[], cmds=[], resp_hdr=[], resp_body=None, expect=""):
|
||||
self.title = title
|
||||
self.cmds = cmds
|
||||
self.include = include
|
||||
self.exclude = exclude
|
||||
self.resp_code = resp_code
|
||||
self.resp_hdr = resp_hdr
|
||||
self.body = resp_body
|
||||
self.expect = expect
|
||||
|
||||
|
||||
class RecvfromCfg:
|
||||
# Test name
|
||||
name = ""
|
||||
# pjsua InstanceParam
|
||||
inst_param = None
|
||||
# List of RecvfromTransaction
|
||||
transaction = None
|
||||
# Use TCP?
|
||||
tcp = False
|
||||
|
||||
# Note:
|
||||
# Any "$PORT" string in the pjsua_args will be replaced
|
||||
# by server port
|
||||
def __init__(self, name, pjsua_args, transaction, tcp=False):
|
||||
self.name = name
|
||||
self.inst_param = cfg.InstanceParam("pjsua", pjsua_args)
|
||||
self.transaction = transaction
|
||||
self.tcp=tcp
|
||||
|
||||
|
||||
|
||||
|
226
res/pjproject/tests/pjsua/mod_call.py
Normal file
226
res/pjproject/tests/pjsua/mod_call.py
Normal file
@@ -0,0 +1,226 @@
|
||||
# $Id$
|
||||
import time
|
||||
import imp
|
||||
import sys
|
||||
import inc_const as const
|
||||
from inc_cfg import *
|
||||
|
||||
# Load configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# Check media flow between ua1 and ua2
|
||||
def check_media(ua1, ua2):
|
||||
ua1.send("#")
|
||||
ua1.expect("#")
|
||||
ua1.send("1122")
|
||||
ua2.expect(const.RX_DTMF + "1")
|
||||
ua2.expect(const.RX_DTMF + "1")
|
||||
ua2.expect(const.RX_DTMF + "2")
|
||||
ua2.expect(const.RX_DTMF + "2")
|
||||
|
||||
|
||||
# Test body function
|
||||
def test_func(t):
|
||||
callee = t.process[0]
|
||||
caller = t.process[1]
|
||||
|
||||
# if have_reg then wait for couple of seconds for PUBLISH
|
||||
# to complete (just in case pUBLISH is used)
|
||||
if callee.inst_param.have_reg:
|
||||
time.sleep(1)
|
||||
if caller.inst_param.have_reg:
|
||||
time.sleep(1)
|
||||
|
||||
# Caller making call
|
||||
caller.send("m")
|
||||
caller.send(t.inst_params[0].uri)
|
||||
caller.expect(const.STATE_CALLING)
|
||||
|
||||
# Callee waits for call and answers with 180/Ringing
|
||||
time.sleep(0.2)
|
||||
callee.expect(const.EVENT_INCOMING_CALL)
|
||||
callee.send("a")
|
||||
callee.send("180")
|
||||
callee.expect("SIP/2.0 180")
|
||||
caller.expect("SIP/2.0 180")
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Callee answers with 200/OK
|
||||
callee.send("a")
|
||||
callee.send("200")
|
||||
|
||||
# Wait until call is connected in both endpoints
|
||||
time.sleep(0.2)
|
||||
caller.expect(const.STATE_CONFIRMED)
|
||||
callee.expect(const.STATE_CONFIRMED)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
time.sleep(0.1)
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is okay
|
||||
time.sleep(0.3)
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# Hold call by caller
|
||||
caller.send("H")
|
||||
caller.expect("INVITE sip:")
|
||||
callee.expect("INVITE sip:")
|
||||
caller.expect(const.MEDIA_HOLD)
|
||||
callee.expect(const.MEDIA_HOLD)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Release hold
|
||||
time.sleep(0.5)
|
||||
caller.send("v")
|
||||
caller.expect("INVITE sip:")
|
||||
callee.expect("INVITE sip:")
|
||||
caller.expect(const.MEDIA_ACTIVE, title="waiting for media active after call hold")
|
||||
callee.expect(const.MEDIA_ACTIVE, title="waiting for media active after call hold")
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is okay
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Hold call by callee
|
||||
callee.send("H")
|
||||
callee.expect("INVITE sip:")
|
||||
caller.expect("INVITE sip:")
|
||||
caller.expect(const.MEDIA_HOLD)
|
||||
callee.expect(const.MEDIA_HOLD)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Release hold
|
||||
time.sleep(0.1)
|
||||
callee.send("v")
|
||||
callee.expect("INVITE sip:")
|
||||
caller.expect("INVITE sip:")
|
||||
callee.expect(const.MEDIA_ACTIVE, title="waiting for media active after call hold")
|
||||
caller.expect(const.MEDIA_ACTIVE, title="waiting for media active after call hold")
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is okay
|
||||
# Wait for some time for ICE negotiation
|
||||
time.sleep(0.6)
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# UPDATE (by caller)
|
||||
caller.send("U")
|
||||
#caller.sync_stdout()
|
||||
callee.expect(const.MEDIA_ACTIVE, title="waiting for media active with UPDATE")
|
||||
caller.expect(const.MEDIA_ACTIVE, title="waiting for media active with UPDATE")
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is okay
|
||||
time.sleep(0.1)
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# UPDATE (by callee)
|
||||
callee.send("U")
|
||||
callee.expect("UPDATE sip:")
|
||||
caller.expect("UPDATE sip:")
|
||||
caller.expect(const.MEDIA_ACTIVE, title="waiting for media active with UPDATE")
|
||||
callee.expect(const.MEDIA_ACTIVE, title="waiting for media active with UPDATE")
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is okay
|
||||
time.sleep(0.1)
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# Synchronize stdout
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Set codecs in both caller and callee so that there is
|
||||
# no common codec between them.
|
||||
# In caller we only enable PCMU, in callee we only enable PCMA
|
||||
caller.send("Cp")
|
||||
caller.expect("Enter codec")
|
||||
caller.send("* 0")
|
||||
caller.send("Cp")
|
||||
caller.expect("Enter codec")
|
||||
caller.send("pcmu 120")
|
||||
|
||||
callee.send("Cp")
|
||||
callee.expect("Enter codec")
|
||||
callee.send("* 0")
|
||||
callee.send("Cp")
|
||||
callee.expect("Enter codec")
|
||||
callee.send("pcma 120")
|
||||
|
||||
# Test when UPDATE fails (by callee)
|
||||
callee.send("U")
|
||||
caller.expect("SIP/2.0 488")
|
||||
callee.expect("SIP/2.0 488")
|
||||
callee.sync_stdout()
|
||||
caller.sync_stdout()
|
||||
|
||||
# Test that media is still okay
|
||||
time.sleep(0.1)
|
||||
check_media(caller, callee)
|
||||
check_media(callee, caller)
|
||||
|
||||
# Test when UPDATE fails (by caller)
|
||||
caller.send("U")
|
||||
caller.expect("UPDATE sip:")
|
||||
callee.expect("UPDATE sip:")
|
||||
callee.expect("SIP/2.0 488")
|
||||
caller.expect("SIP/2.0 488")
|
||||
caller.sync_stdout()
|
||||
callee.sync_stdout()
|
||||
|
||||
# Test that media is still okay
|
||||
time.sleep(0.1)
|
||||
check_media(callee, caller)
|
||||
check_media(caller, callee)
|
||||
|
||||
# Hangup call
|
||||
time.sleep(0.1)
|
||||
caller.send("h")
|
||||
|
||||
# Wait until calls are cleared in both endpoints
|
||||
caller.expect(const.STATE_DISCONNECTED)
|
||||
callee.expect(const.STATE_DISCONNECTED)
|
||||
|
||||
|
||||
# Here where it all comes together
|
||||
test = cfg_file.test_param
|
||||
test.test_func = test_func
|
||||
|
108
res/pjproject/tests/pjsua/mod_media_playrec.py
Normal file
108
res/pjproject/tests/pjsua/mod_media_playrec.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# $Id$
|
||||
|
||||
# PLAYFILE -> RECFILE:
|
||||
# Input file is played and is recorded to output, then compare them.
|
||||
# Useful to tes clock rates compatibility and resample quality
|
||||
# null-audio
|
||||
# port 1: wav file input xxxxxx.clock_rate.wav, e.g: test1.8.wav
|
||||
# port 2: wav file ouput xxxxxx.clock_rate.wav, e.g: res1.8.wav
|
||||
# wav input must be more than 3 seconds long
|
||||
|
||||
import time
|
||||
import imp
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
import inc_const as const
|
||||
from inc_cfg import *
|
||||
|
||||
# Load configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# WAV similarity calculator
|
||||
COMPARE_WAV_EXE = ""
|
||||
if sys.platform.find("win32")!=-1:
|
||||
COMPARE_WAV_EXE = "tools/cmp_wav.exe"
|
||||
G_INUNIX = False
|
||||
else:
|
||||
COMPARE_WAV_EXE = "tools/cmp_wav"
|
||||
G_INUNIX = True
|
||||
|
||||
|
||||
# Threshold to declare degradation is too high when result is lower than this value
|
||||
COMPARE_THRESHOLD = 2
|
||||
|
||||
# COMPARE params
|
||||
input_filename = "" # Input filename
|
||||
output_filename = "" # Output filename
|
||||
|
||||
# Test body function
|
||||
def test_func(t):
|
||||
global input_filename
|
||||
global output_filename
|
||||
|
||||
endpt = t.process[0]
|
||||
|
||||
# Get input file name
|
||||
input_filename = re.compile(const.MEDIA_PLAY_FILE).search(endpt.inst_param.arg).group(1)
|
||||
endpt.trace("Input file = " + input_filename)
|
||||
|
||||
# Get output file name
|
||||
output_filename = re.compile(const.MEDIA_REC_FILE).search(endpt.inst_param.arg).group(1)
|
||||
endpt.trace("Output file = " + output_filename)
|
||||
|
||||
# Find appropriate clock rate for the input file
|
||||
clock_rate = re.compile(".+(\.\d+\.wav)$").match(output_filename).group(1)
|
||||
if (clock_rate==None):
|
||||
endpt.trace("Cannot compare input & output, incorrect output filename format")
|
||||
return
|
||||
input_filename = re.sub("\.\d+\.wav$", clock_rate, input_filename)
|
||||
endpt.trace("WAV file to be compared with output = " + input_filename)
|
||||
|
||||
# Connect input-output file
|
||||
endpt.sync_stdout()
|
||||
|
||||
endpt.send("cc 1 2")
|
||||
endpt.expect(const.MEDIA_CONN_PORT_SUCCESS)
|
||||
|
||||
# Wait
|
||||
time.sleep(3)
|
||||
|
||||
endpt.sync_stdout()
|
||||
|
||||
# Disconnect input-output file
|
||||
endpt.send("cd 1 2")
|
||||
endpt.expect(const.MEDIA_DISCONN_PORT_SUCCESS)
|
||||
|
||||
|
||||
# Post body function
|
||||
def post_func(t):
|
||||
global input_filename
|
||||
global output_filename
|
||||
|
||||
endpt = t.process[0]
|
||||
|
||||
# Check WAV similarity
|
||||
fullcmd = COMPARE_WAV_EXE + " " + input_filename + " " + output_filename + " " + "3000"
|
||||
endpt.trace("Popen " + fullcmd)
|
||||
cmp_proc = subprocess.Popen(fullcmd, shell=G_INUNIX, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
|
||||
# Parse similarity ouput
|
||||
line = cmp_proc.stdout.readline()
|
||||
mo_sim_val = re.match(".+=\s+(\d+)", line)
|
||||
if (mo_sim_val == None):
|
||||
raise TestError("Error comparing WAV files")
|
||||
return
|
||||
|
||||
# Evaluate the similarity value
|
||||
sim_val = mo_sim_val.group(1)
|
||||
if (sim_val >= COMPARE_THRESHOLD):
|
||||
endpt.trace("WAV similarity = " + sim_val)
|
||||
else:
|
||||
raise TestError("WAV degraded heavily, similarity = " + sim_val)
|
||||
|
||||
|
||||
# Here where it all comes together
|
||||
test = cfg_file.test_param
|
||||
test.test_func = test_func
|
||||
test.post_func = post_func
|
167
res/pjproject/tests/pjsua/mod_pesq.py
Normal file
167
res/pjproject/tests/pjsua/mod_pesq.py
Normal file
@@ -0,0 +1,167 @@
|
||||
# $Id$
|
||||
|
||||
# Quality test of media calls.
|
||||
# - UA1 calls UA2
|
||||
# - UA1 plays a file until finished to be streamed to UA2
|
||||
# - UA2 records from stream
|
||||
# - Apply PESQ to played file (reference) and recorded file (degraded)
|
||||
#
|
||||
# File should be:
|
||||
# - naming: xxxxxx.CLOCK_RATE.wav, e.g: test1.8.wav
|
||||
# - clock-rate of those files can only be 8khz or 16khz
|
||||
|
||||
import time
|
||||
import imp
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import subprocess
|
||||
import wave
|
||||
import shutil
|
||||
import inc_const as const
|
||||
|
||||
from inc_cfg import *
|
||||
|
||||
# Load configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# PESQ configs
|
||||
PESQ = "tools/pesq" # PESQ executable path
|
||||
PESQ_DEFAULT_THRESHOLD = 3.4 # Default minimum acceptable PESQ MOS value
|
||||
|
||||
# PESQ params
|
||||
pesq_sample_rate_opt = "" # Sample rate option for PESQ
|
||||
input_filename = "" # Input/Reference filename
|
||||
output_filename = "" # Output/Degraded filename
|
||||
|
||||
|
||||
# Test body function
|
||||
def test_func(t):
|
||||
global pesq_sample_rate_opt
|
||||
global input_filename
|
||||
global output_filename
|
||||
|
||||
ua1 = t.process[0]
|
||||
ua2 = t.process[1]
|
||||
|
||||
# Get input file name
|
||||
input_filename = re.compile(const.MEDIA_PLAY_FILE).search(ua1.inst_param.arg).group(1)
|
||||
|
||||
# Get output file name
|
||||
output_filename = re.compile(const.MEDIA_REC_FILE).search(ua2.inst_param.arg).group(1)
|
||||
|
||||
# Get WAV input length, in seconds
|
||||
fin = wave.open(input_filename, "r")
|
||||
if fin == None:
|
||||
raise TestError("Failed opening input WAV file")
|
||||
inwavlen = fin.getnframes() * 1.0 / fin.getframerate()
|
||||
inwavlen += 0.2
|
||||
fin.close()
|
||||
print "WAV input len = " + str(inwavlen) + "s"
|
||||
|
||||
# Get clock rate of the output
|
||||
mo_clock_rate = re.compile("\.(\d+)\.wav").search(output_filename)
|
||||
if (mo_clock_rate==None):
|
||||
raise TestError("Cannot compare input & output, incorrect output filename format")
|
||||
clock_rate = mo_clock_rate.group(1)
|
||||
|
||||
# Get channel count of the output
|
||||
channel_count = 1
|
||||
if re.search("--stereo", ua2.inst_param.arg) != None:
|
||||
channel_count = 2
|
||||
|
||||
# Get matched input file from output file
|
||||
# (PESQ evaluates only files whose same clock rate & channel count)
|
||||
if channel_count == 2:
|
||||
if re.search("\.\d+\.\d+\.wav", input_filename) != None:
|
||||
input_filename = re.sub("\.\d+\.\d+\.wav", "." + str(channel_count) + "."+clock_rate+".wav", input_filename)
|
||||
else:
|
||||
input_filename = re.sub("\.\d+\.wav", "." + str(channel_count) + "."+clock_rate+".wav", input_filename)
|
||||
|
||||
if (clock_rate != "8") & (clock_rate != "16"):
|
||||
raise TestError("PESQ only works on clock rate 8kHz or 16kHz, clock rate used = "+clock_rate+ "kHz")
|
||||
|
||||
# Get conference clock rate of UA2 for PESQ sample rate option
|
||||
pesq_sample_rate_opt = "+" + clock_rate + "000"
|
||||
|
||||
# UA1 making call
|
||||
ua1.send("m")
|
||||
ua1.send(t.inst_params[1].uri)
|
||||
ua1.expect(const.STATE_CALLING)
|
||||
|
||||
# UA2 wait until call established
|
||||
ua2.expect(const.STATE_CONFIRMED)
|
||||
|
||||
ua1.sync_stdout()
|
||||
ua2.sync_stdout()
|
||||
time.sleep(2)
|
||||
|
||||
# Disconnect mic -> rec file, to avoid echo recorded when using sound device
|
||||
# Disconnect stream -> spk, make it silent
|
||||
# Connect stream -> rec file, start recording
|
||||
ua2.send("cd 0 1\ncd 4 0\ncc 4 1")
|
||||
|
||||
# Disconnect mic -> stream, make stream purely sending from file
|
||||
# Disconnect stream -> spk, make it silent
|
||||
# Connect file -> stream, start sending
|
||||
ua1.send("cd 0 4\ncd 4 0\ncc 1 4")
|
||||
|
||||
time.sleep(inwavlen)
|
||||
|
||||
# Disconnect files from bridge
|
||||
ua2.send("cd 4 1")
|
||||
ua2.expect(const.MEDIA_DISCONN_PORT_SUCCESS)
|
||||
ua1.send("cd 1 4")
|
||||
ua1.expect(const.MEDIA_DISCONN_PORT_SUCCESS)
|
||||
|
||||
|
||||
# Post body function
|
||||
def post_func(t):
|
||||
global pesq_sample_rate_opt
|
||||
global input_filename
|
||||
global output_filename
|
||||
|
||||
endpt = t.process[0]
|
||||
|
||||
# Execute PESQ
|
||||
fullcmd = os.path.normpath(PESQ) + " " + pesq_sample_rate_opt + " " + input_filename + " " + output_filename
|
||||
endpt.trace("Popen " + fullcmd)
|
||||
pesq_proc = subprocess.Popen(fullcmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
|
||||
pesq_out = pesq_proc.communicate()
|
||||
|
||||
# Parse ouput
|
||||
mo_pesq_out = re.compile("Prediction[^=]+=\s+([\-\d\.]+)\s*").search(pesq_out[0])
|
||||
if (mo_pesq_out == None):
|
||||
raise TestError("Failed to fetch PESQ result")
|
||||
|
||||
# Get threshold
|
||||
if (cfg_file.pesq_threshold != None) | (cfg_file.pesq_threshold > -0.5 ):
|
||||
threshold = cfg_file.pesq_threshold
|
||||
else:
|
||||
threshold = PESQ_DEFAULT_THRESHOLD
|
||||
|
||||
# Evaluate the PESQ MOS value
|
||||
pesq_res = mo_pesq_out.group(1)
|
||||
if (float(pesq_res) >= threshold):
|
||||
endpt.trace("Success, PESQ result = " + pesq_res + " (target=" + str(threshold) + ").")
|
||||
else:
|
||||
endpt.trace("Failed, PESQ result = " + pesq_res + " (target=" + str(threshold) + ").")
|
||||
# Save the wav file
|
||||
wavoutname = ARGS[1]
|
||||
wavoutname = re.sub("[\\\/]", "_", wavoutname)
|
||||
wavoutname = re.sub("\.py$", ".wav", wavoutname)
|
||||
wavoutname = "logs/" + wavoutname
|
||||
try:
|
||||
shutil.copyfile(output_filename, wavoutname)
|
||||
print "Output WAV is copied to " + wavoutname
|
||||
except:
|
||||
print "Couldn't copy output WAV, please check if 'logs' directory exists."
|
||||
|
||||
raise TestError("WAV seems to be degraded badly, PESQ = "+ pesq_res + " (target=" + str(threshold) + ").")
|
||||
|
||||
|
||||
# Here where it all comes together
|
||||
test = cfg_file.test_param
|
||||
test.test_func = test_func
|
||||
test.post_func = post_func
|
||||
|
125
res/pjproject/tests/pjsua/mod_pres.py
Normal file
125
res/pjproject/tests/pjsua/mod_pres.py
Normal file
@@ -0,0 +1,125 @@
|
||||
# $Id$
|
||||
import time
|
||||
import imp
|
||||
import sys
|
||||
import inc_const as const
|
||||
from inc_cfg import *
|
||||
|
||||
# Load configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
|
||||
# Test body function
|
||||
def test_func(t):
|
||||
u1 = t.process[0]
|
||||
uri1 = cfg_file.test_param.inst_params[0].uri
|
||||
acc1 = "-1"
|
||||
u2 = t.process[1]
|
||||
uri2 = cfg_file.test_param.inst_params[1].uri
|
||||
acc2 = "-1"
|
||||
|
||||
# if have_reg then wait for couple of seconds for PUBLISH
|
||||
# to complete (just in case pUBLISH is used)
|
||||
if u1.inst_param.have_reg:
|
||||
time.sleep(1)
|
||||
if u2.inst_param.have_reg:
|
||||
time.sleep(1)
|
||||
|
||||
# U1 adds U2 as buddy
|
||||
u1.send("+b")
|
||||
u1.send(uri2)
|
||||
u1.expect("Subscription state changed NULL --> SENT")
|
||||
u1.expect("Presence subscription.*is ACCEPTED")
|
||||
if not u2.inst_param.have_publish:
|
||||
# Process incoming SUBSCRIBE in U2
|
||||
# Finds out which account gets the subscription in U2
|
||||
line = u2.expect("pjsua_pres.*subscription.*using account")
|
||||
acc2 = line.split("using account ")[1]
|
||||
# wait until we've got Online notification
|
||||
u1.expect(uri2 + ".*Online")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# U2 adds U1 as buddy
|
||||
u2.send("+b")
|
||||
u2.send(uri1)
|
||||
u2.expect("Subscription state changed NULL --> SENT")
|
||||
u2.expect("Presence subscription.*is ACCEPTED")
|
||||
if not u1.inst_param.have_publish:
|
||||
# Process incoming SUBSCRIBE in U1
|
||||
# Finds out which account gets the subscription in U1
|
||||
line = u1.expect("pjsua_pres.*subscription.*using account")
|
||||
acc1 = line.split("using account ")[1]
|
||||
# wait until we've got Online notification
|
||||
u2.expect(uri1 + ".*Online")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# Set current account in both U1 and U2
|
||||
if acc1!="-1":
|
||||
u1.send(">")
|
||||
u1.send(acc1)
|
||||
u1.expect("Current account changed")
|
||||
if acc2!="-1":
|
||||
u2.send(">")
|
||||
u2.send(acc2)
|
||||
u2.expect("Current account changed")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# u2 toggles online status
|
||||
u2.send("t")
|
||||
u1.expect(uri2 + ".*status.*Offline")
|
||||
u2.expect("offline")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# u1 toggles online status
|
||||
u1.send("t")
|
||||
u2.expect(uri1 + ".*status.*Offline")
|
||||
u1.expect("offline")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# u2 set online status to On the phone
|
||||
u2.send("T")
|
||||
u2.send("3")
|
||||
u1.expect(uri2 + ".*status.*On the phone")
|
||||
u2.expect("On the phone")
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
# U1 send IM
|
||||
im_text = "Hello World from U1"
|
||||
u1.send("i")
|
||||
u1.send(uri2)
|
||||
u2.expect(" is typing")
|
||||
u1.send(im_text)
|
||||
u1.expect(im_text+".*delivered successfully")
|
||||
u2.expect("MESSAGE from.*"+im_text)
|
||||
|
||||
# Synchronize stdout
|
||||
u1.sync_stdout()
|
||||
u2.sync_stdout()
|
||||
|
||||
|
||||
# Here where it all comes together
|
||||
test = cfg_file.test_param
|
||||
test.test_func = test_func
|
||||
|
97
res/pjproject/tests/pjsua/mod_recvfrom.py
Normal file
97
res/pjproject/tests/pjsua/mod_recvfrom.py
Normal file
@@ -0,0 +1,97 @@
|
||||
# $Id$
|
||||
import imp
|
||||
import sys
|
||||
import inc_sip as sip
|
||||
import inc_const as const
|
||||
import re
|
||||
from inc_cfg import *
|
||||
|
||||
# Read configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# Default server port (should we randomize?)
|
||||
srv_port = 50070
|
||||
|
||||
def test_func(test):
|
||||
pjsua = test.process[0]
|
||||
dlg = sip.Dialog("127.0.0.1", pjsua.inst_param.sip_port,
|
||||
local_port=srv_port,
|
||||
tcp=cfg_file.recvfrom_cfg.tcp)
|
||||
|
||||
last_cseq = 0
|
||||
last_method = ""
|
||||
last_call_id = ""
|
||||
for t in cfg_file.recvfrom_cfg.transaction:
|
||||
# Print transaction title
|
||||
if t.title != "":
|
||||
dlg.trace(t.title)
|
||||
# Run command and expect patterns
|
||||
for c in t.cmds:
|
||||
if c[0] and c[0] != "":
|
||||
pjsua.send(c[0])
|
||||
if len(c)>1 and c[1] and c[1] != "":
|
||||
pjsua.expect(c[1])
|
||||
# Wait for request
|
||||
if t.check_cseq:
|
||||
# Absorbs retransmissions
|
||||
cseq = 0
|
||||
method = last_method
|
||||
call_id = last_call_id
|
||||
while cseq <= last_cseq and method == last_method and call_id == last_call_id:
|
||||
request, src_addr = dlg.wait_msg_from(30)
|
||||
if request==None or request=="":
|
||||
raise TestError("Timeout waiting for request")
|
||||
method = request.split(" ", 1)[0]
|
||||
cseq_hval = sip.get_header(request, "CSeq")
|
||||
cseq_hval = cseq_hval.split(" ")[0]
|
||||
cseq = int(cseq_hval)
|
||||
call_id = sip.get_header(request, "Call-ID")
|
||||
last_cseq = cseq
|
||||
last_method = method
|
||||
else:
|
||||
request, src_addr = dlg.wait_msg_from(30)
|
||||
if request==None or request=="":
|
||||
raise TestError("Timeout waiting for request")
|
||||
|
||||
# Check for include patterns
|
||||
for pat in t.include:
|
||||
if re.search(pat, request, re.M | re.I)==None:
|
||||
if t.title:
|
||||
tname = " in " + t.title + " transaction"
|
||||
else:
|
||||
tname = ""
|
||||
raise TestError("Pattern " + pat + " not found" + tname)
|
||||
# Check for exclude patterns
|
||||
for pat in t.exclude:
|
||||
if re.search(pat, request, re.M | re.I)!=None:
|
||||
if t.title:
|
||||
tname = " in " + t.title + " transaction"
|
||||
else:
|
||||
tname = ""
|
||||
raise TestError("Excluded pattern " + pat + " found" + tname)
|
||||
# Create response
|
||||
if t.resp_code!=0:
|
||||
response = dlg.create_response(request, t.resp_code, "Status reason")
|
||||
# Add headers to response
|
||||
for h in t.resp_hdr:
|
||||
response = response + h + "\r\n"
|
||||
# Add message body if required
|
||||
if t.body:
|
||||
response = response + t.body
|
||||
# Send response
|
||||
dlg.send_msg(response, src_addr)
|
||||
|
||||
# Expect something to happen in pjsua
|
||||
if t.expect != "":
|
||||
pjsua.expect(t.expect)
|
||||
# Sync
|
||||
pjsua.sync_stdout()
|
||||
|
||||
# Replace "$PORT" with server port in pjsua args
|
||||
cfg_file.recvfrom_cfg.inst_param.arg = cfg_file.recvfrom_cfg.inst_param.arg.replace("$PORT", str(srv_port))
|
||||
|
||||
# Here where it all comes together
|
||||
test = TestParam(cfg_file.recvfrom_cfg.name,
|
||||
[cfg_file.recvfrom_cfg.inst_param],
|
||||
test_func)
|
||||
|
11
res/pjproject/tests/pjsua/mod_run.py
Normal file
11
res/pjproject/tests/pjsua/mod_run.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
import imp
|
||||
import sys
|
||||
|
||||
from inc_cfg import *
|
||||
|
||||
# Read configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# Here where it all comes together
|
||||
test = cfg_file.test_param
|
53
res/pjproject/tests/pjsua/mod_sendto.py
Normal file
53
res/pjproject/tests/pjsua/mod_sendto.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# $Id$
|
||||
import imp
|
||||
import sys
|
||||
import inc_sip as sip
|
||||
import inc_const as const
|
||||
import re
|
||||
from inc_cfg import *
|
||||
|
||||
# Read configuration
|
||||
cfg_file = imp.load_source("cfg_file", ARGS[1])
|
||||
|
||||
# Test body function
|
||||
def test_func(t):
|
||||
pjsua = t.process[0]
|
||||
# Create dialog
|
||||
dlg = sip.Dialog("127.0.0.1", pjsua.inst_param.sip_port,
|
||||
tcp=cfg_file.sendto_cfg.use_tcp)
|
||||
#dlg = sip.Dialog("127.0.0.1", 5060, tcp=cfg_file.sendto_cfg.use_tcp)
|
||||
cfg = cfg_file.sendto_cfg
|
||||
|
||||
if len(cfg.complete_msg) != 0:
|
||||
req = dlg.update_fields(cfg.complete_msg)
|
||||
else:
|
||||
req = dlg.create_invite(cfg.sdp, cfg.extra_headers, cfg.body)
|
||||
resp = dlg.send_request_wait(req, 10)
|
||||
if resp=="":
|
||||
raise TestError("Timed-out waiting for response")
|
||||
# Check response code
|
||||
code = int(sip.get_code(resp))
|
||||
if code != cfg.resp_code:
|
||||
dlg.hangup(code)
|
||||
raise TestError("Expecting code " + str(cfg.resp_code) +
|
||||
" got " + str(code))
|
||||
# Check for patterns that must exist
|
||||
for p in cfg.resp_include:
|
||||
if re.search(p, resp, re.M | re.I)==None:
|
||||
dlg.hangup(code)
|
||||
raise TestError("Pattern " + p + " not found")
|
||||
# Check for patterns that must not exist
|
||||
for p in cfg.resp_exclude:
|
||||
if re.search(p, resp, re.M | re.I)!=None:
|
||||
dlg.hangup(code)
|
||||
raise TestError("Excluded pattern " + p + " found")
|
||||
pjsua.sync_stdout()
|
||||
dlg.hangup(code)
|
||||
pjsua.sync_stdout()
|
||||
|
||||
# Here where it all comes together
|
||||
test = TestParam(cfg_file.sendto_cfg.name,
|
||||
[cfg_file.sendto_cfg.inst_param],
|
||||
test_func)
|
||||
|
||||
|
289
res/pjproject/tests/pjsua/run.py
Normal file
289
res/pjproject/tests/pjsua/run.py
Normal file
@@ -0,0 +1,289 @@
|
||||
# $Id$
|
||||
import sys
|
||||
import imp
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
import random
|
||||
import time
|
||||
import getopt
|
||||
|
||||
import inc_const as const
|
||||
import inc_cfg as inc
|
||||
|
||||
# Vars
|
||||
G_EXE = "" # pjsua executable path
|
||||
G_INUNIX = False # flags that test is running in Unix
|
||||
|
||||
|
||||
# Usage string
|
||||
usage = \
|
||||
"""
|
||||
run.py - Automated test driver
|
||||
|
||||
Usage:
|
||||
run.py [options] MODULE CONFIG
|
||||
Options:
|
||||
--exe, -e pjsua executable path
|
||||
--null-audio, -n use null audio
|
||||
Sample:
|
||||
run.py -n mod_run.py scripts-run/100_simple.py
|
||||
"""
|
||||
|
||||
# Parse arguments
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "hne:", ["help", "null-audio", "exe="])
|
||||
except getopt.GetoptError, err:
|
||||
print str(err)
|
||||
print usage
|
||||
sys.exit(2)
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print usage
|
||||
sys.exit()
|
||||
elif o in ("-n", "--null-audio"):
|
||||
inc.HAS_SND_DEV = 0
|
||||
elif o in ("-e", "--exe"):
|
||||
G_EXE = a
|
||||
else:
|
||||
print "Unknown options"
|
||||
sys.exit(2)
|
||||
|
||||
if len(args) != 2:
|
||||
print "Invalid arguments"
|
||||
print usage
|
||||
sys.exit(2)
|
||||
|
||||
# Set global ARGS to be used by modules
|
||||
inc.ARGS = args
|
||||
|
||||
# Get the pjsua executable name
|
||||
if G_EXE == "":
|
||||
if sys.platform.find("win32")!=-1:
|
||||
EXE_DIR = "../../pjsip-apps/bin/"
|
||||
EXECUTABLES = [ "pjsua_vc6d.exe",
|
||||
"pjsua_vc6.exe",
|
||||
"pjsua-i386-Win32-vc8-Debug.exe",
|
||||
"pjsua-i386-Win32-vc8-Debug-Dynamic.exe",
|
||||
"pjsua-i386-Win32-vc8-Debug-Static.exe",
|
||||
"pjsua-i386-Win32-vc8-Release.exe",
|
||||
"pjsua-i386-Win32-vc8-Release-Dynamic.exe",
|
||||
"pjsua-i386-Win32-vc8-Release-Static.exe"
|
||||
]
|
||||
e_ts = 0
|
||||
for e in EXECUTABLES:
|
||||
e = EXE_DIR + e
|
||||
if os.access(e, os.F_OK):
|
||||
st = os.stat(e)
|
||||
if e_ts==0 or e_ts<st.st_mtime:
|
||||
G_EXE = e
|
||||
e_ts = st.st_mtime
|
||||
|
||||
if G_EXE=="":
|
||||
print "Unable to find valid pjsua. Please build pjsip first"
|
||||
sys.exit(1)
|
||||
|
||||
G_INUNIX = False
|
||||
else:
|
||||
f = open("../../build.mak", "r")
|
||||
while True:
|
||||
line = f.readline()
|
||||
if not line:
|
||||
break
|
||||
if line.find("TARGET_NAME")!=-1:
|
||||
print line
|
||||
G_EXE="../../pjsip-apps/bin/pjsua-" + line.split(":= ")[1]
|
||||
break
|
||||
if G_EXE=="":
|
||||
print "Unable to find ../../../build.mak. Please build pjsip first"
|
||||
sys.exit(1)
|
||||
G_INUNIX = True
|
||||
else:
|
||||
if sys.platform.lower().find("win32")!=-1 or sys.platform.lower().find("microsoft")!=-1:
|
||||
G_INUNIX = False
|
||||
else:
|
||||
G_INUNIX = True
|
||||
|
||||
|
||||
G_EXE = G_EXE.rstrip("\n\r \t")
|
||||
|
||||
###################################
|
||||
# Poor man's 'expect'-like class
|
||||
class Expect:
|
||||
proc = None
|
||||
echo = False
|
||||
trace_enabled = False
|
||||
name = ""
|
||||
inst_param = None
|
||||
rh = re.compile(const.DESTROYED)
|
||||
ra = re.compile(const.ASSERT, re.I)
|
||||
rr = re.compile(const.STDOUT_REFRESH)
|
||||
t0 = time.time()
|
||||
def __init__(self, inst_param):
|
||||
self.inst_param = inst_param
|
||||
self.name = inst_param.name
|
||||
self.echo = inst_param.echo_enabled
|
||||
self.trace_enabled = inst_param.trace_enabled
|
||||
fullcmd = G_EXE + " " + inst_param.arg + " --stdout-refresh=5 --stdout-refresh-text=" + const.STDOUT_REFRESH
|
||||
if not inst_param.enable_buffer:
|
||||
fullcmd = fullcmd + " --stdout-no-buf"
|
||||
self.trace("Popen " + fullcmd)
|
||||
self.proc = subprocess.Popen(fullcmd, shell=G_INUNIX, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=False)
|
||||
def send(self, cmd):
|
||||
self.trace("send " + cmd)
|
||||
self.proc.stdin.writelines(cmd + "\n")
|
||||
self.proc.stdin.flush()
|
||||
def expect(self, pattern, raise_on_error=True, title=""):
|
||||
self.trace("expect " + pattern)
|
||||
r = re.compile(pattern, re.I)
|
||||
refresh_cnt = 0
|
||||
while True:
|
||||
line = self.proc.stdout.readline()
|
||||
if line == "":
|
||||
raise inc.TestError(self.name + ": Premature EOF")
|
||||
# Print the line if echo is ON
|
||||
if self.echo:
|
||||
print self.name + ": " + line,
|
||||
# Trap assertion error
|
||||
if self.ra.search(line) != None:
|
||||
if raise_on_error:
|
||||
raise inc.TestError(self.name + ": " + line)
|
||||
else:
|
||||
return None
|
||||
# Count stdout refresh text.
|
||||
if self.rr.search(line) != None:
|
||||
refresh_cnt = refresh_cnt+1
|
||||
if refresh_cnt >= 6:
|
||||
self.trace("Timed-out!")
|
||||
if raise_on_error:
|
||||
raise inc.TestError(self.name + " " + title + ": Timeout expecting pattern: \"" + pattern + "\"")
|
||||
else:
|
||||
return None # timeout
|
||||
# Search for expected text
|
||||
if r.search(line) != None:
|
||||
return line
|
||||
|
||||
def sync_stdout(self):
|
||||
self.trace("sync_stdout")
|
||||
cmd = "echo 1" + str(random.randint(1000,9999))
|
||||
self.send(cmd)
|
||||
self.expect(cmd)
|
||||
|
||||
def wait(self):
|
||||
self.trace("wait")
|
||||
self.proc.communicate()
|
||||
|
||||
def trace(self, s):
|
||||
if self.trace_enabled:
|
||||
now = time.time()
|
||||
fmt = self.name + ": " + "================== " + s + " ==================" + " [at t=%(time)03d]"
|
||||
print fmt % {'time':int(now - self.t0)}
|
||||
|
||||
#########################
|
||||
# Error handling
|
||||
def handle_error(errmsg, t, close_processes = True):
|
||||
print "====== Caught error: " + errmsg + " ======"
|
||||
if (close_processes):
|
||||
time.sleep(1)
|
||||
for p in t.process:
|
||||
# Protect against 'Broken pipe' exception
|
||||
try:
|
||||
p.send("q")
|
||||
p.send("q")
|
||||
except:
|
||||
pass
|
||||
is_err = False
|
||||
try:
|
||||
ret = p.expect(const.DESTROYED, False)
|
||||
if not ret:
|
||||
is_err = True
|
||||
except:
|
||||
is_err = True
|
||||
if is_err:
|
||||
if sys.hexversion >= 0x02060000:
|
||||
p.proc.terminate()
|
||||
else:
|
||||
p.wait()
|
||||
else:
|
||||
p.wait()
|
||||
print "Test completed with error: " + errmsg
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
#########################
|
||||
# MAIN
|
||||
|
||||
# Import the test script
|
||||
script = imp.load_source("script", inc.ARGS[0])
|
||||
|
||||
# Init random seed
|
||||
random.seed()
|
||||
|
||||
# Validate
|
||||
if script.test == None:
|
||||
print "Error: no test defined"
|
||||
sys.exit(1)
|
||||
|
||||
if script.test.skip:
|
||||
print "Test " + script.test.title + " is skipped"
|
||||
sys.exit(0)
|
||||
|
||||
if len(script.test.inst_params) == 0:
|
||||
print "Error: test doesn't contain pjsua run descriptions"
|
||||
sys.exit(1)
|
||||
|
||||
# Instantiate pjsuas
|
||||
print "====== Running " + script.test.title + " ======"
|
||||
print "Using " + G_EXE + " as pjsua executable"
|
||||
|
||||
for inst_param in script.test.inst_params:
|
||||
try:
|
||||
# Create pjsua's Expect instance from the param
|
||||
p = Expect(inst_param)
|
||||
# Wait until registration completes
|
||||
if inst_param.have_reg:
|
||||
p.expect(inst_param.uri+".*registration success")
|
||||
# Synchronize stdout
|
||||
p.send("")
|
||||
p.expect(const.PROMPT)
|
||||
p.send("echo 1")
|
||||
p.send("echo 1")
|
||||
p.expect("echo 1")
|
||||
# add running instance
|
||||
script.test.process.append(p)
|
||||
|
||||
except inc.TestError, e:
|
||||
handle_error(e.desc, script.test)
|
||||
|
||||
# Run the test function
|
||||
if script.test.test_func != None:
|
||||
try:
|
||||
script.test.test_func(script.test)
|
||||
except inc.TestError, e:
|
||||
handle_error(e.desc, script.test)
|
||||
|
||||
# Shutdown all instances
|
||||
time.sleep(2)
|
||||
for p in script.test.process:
|
||||
# Unregister if we have_reg to make sure that next tests
|
||||
# won't wail
|
||||
if p.inst_param.have_reg:
|
||||
p.send("ru")
|
||||
p.expect(p.inst_param.uri+".*unregistration success")
|
||||
p.send("q")
|
||||
p.send("q")
|
||||
time.sleep(0.5)
|
||||
p.expect(const.DESTROYED, False)
|
||||
p.wait()
|
||||
|
||||
# Run the post test function
|
||||
if script.test.post_func != None:
|
||||
try:
|
||||
script.test.post_func(script.test)
|
||||
except inc.TestError, e:
|
||||
handle_error(e.desc, script.test, False)
|
||||
|
||||
# Done
|
||||
print "Test " + script.test.title + " completed successfully"
|
||||
sys.exit(0)
|
||||
|
178
res/pjproject/tests/pjsua/runall.py
Normal file
178
res/pjproject/tests/pjsua/runall.py
Normal file
@@ -0,0 +1,178 @@
|
||||
# $Id$
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import re
|
||||
import shutil
|
||||
|
||||
PYTHON = os.path.basename(sys.executable)
|
||||
|
||||
# Usage:
|
||||
# runall.py [test-to-resume]
|
||||
|
||||
|
||||
# Initialize test list
|
||||
tests = []
|
||||
|
||||
# Excluded tests (because they fail?)
|
||||
excluded_tests = [ "svn",
|
||||
"pyc",
|
||||
"scripts-call/150_srtp_2_1", # SRTP optional 'cannot' call SRTP mandatory
|
||||
"scripts-call/150_srtp_2_3.py", # temporarily disabled until #1267 done
|
||||
"scripts-call/301_ice_public_a.py", # Unreliable, proxy returns 408 sometimes
|
||||
"scripts-call/301_ice_public_b.py", # Doesn't work because OpenSER modifies SDP
|
||||
"scripts-pres/200_publish.py", # Ok from cmdline, error from runall.py
|
||||
"scripts-media-playrec/100_resample_lf_8_11.py", # related to clock-rate 11 kHz problem
|
||||
"scripts-media-playrec/100_resample_lf_8_22.py", # related to clock-rate 22 kHz problem
|
||||
"scripts-media-playrec/100_resample_lf_11" # related to clock-rate 11 kHz problem
|
||||
]
|
||||
|
||||
# Add basic tests
|
||||
for f in os.listdir("scripts-run"):
|
||||
tests.append("mod_run.py scripts-run/" + f)
|
||||
|
||||
# Add basic call tests
|
||||
for f in os.listdir("scripts-call"):
|
||||
tests.append("mod_call.py scripts-call/" + f)
|
||||
|
||||
# Add presence tests
|
||||
for f in os.listdir("scripts-pres"):
|
||||
tests.append("mod_pres.py scripts-pres/" + f)
|
||||
|
||||
# Add mod_sendto tests
|
||||
for f in os.listdir("scripts-sendto"):
|
||||
tests.append("mod_sendto.py scripts-sendto/" + f)
|
||||
|
||||
# Add mod_media_playrec tests
|
||||
for f in os.listdir("scripts-media-playrec"):
|
||||
tests.append("mod_media_playrec.py scripts-media-playrec/" + f)
|
||||
|
||||
# Add mod_pesq tests
|
||||
for f in os.listdir("scripts-pesq"):
|
||||
tests.append("mod_pesq.py scripts-pesq/" + f)
|
||||
|
||||
# Add recvfrom tests
|
||||
for f in os.listdir("scripts-recvfrom"):
|
||||
tests.append("mod_recvfrom.py scripts-recvfrom/" + f)
|
||||
|
||||
# Filter-out excluded tests
|
||||
for pat in excluded_tests:
|
||||
tests = [t for t in tests if t.find(pat)==-1]
|
||||
|
||||
|
||||
resume_script=""
|
||||
shell_cmd=""
|
||||
|
||||
# Parse arguments
|
||||
sys.argv.pop(0)
|
||||
while len(sys.argv):
|
||||
if sys.argv[0]=='/h' or sys.argv[0]=='-h' or sys.argv[0]=='--help' or sys.argv[0]=='/help':
|
||||
sys.argv.pop(0)
|
||||
print "Usage:"
|
||||
print " runall.py [OPTIONS] [run.py-OPTIONS]"
|
||||
print "OPTIONS:"
|
||||
print " --list"
|
||||
print " List the tests"
|
||||
print " --list-xml"
|
||||
print " List the tests as XML format suitable for ccdash"
|
||||
print " --resume,-r RESUME"
|
||||
print " RESUME is string/substring to specify where to resume tests."
|
||||
print " If this argument is omited, tests will start from the beginning."
|
||||
print " --shell,-s SHELL"
|
||||
print " Run the tests with the specified SHELL cmd. This can also be"
|
||||
print " used to run the test with ccdash. Example:"
|
||||
print " --shell '/bin/sh -c'"
|
||||
print " run.py-OPTIONS are applicable here"
|
||||
sys.exit(0)
|
||||
elif sys.argv[0] == '-r' or sys.argv[0] == '--resume':
|
||||
if len(sys.argv) > 1:
|
||||
resume_script=sys.argv[1]
|
||||
sys.argv.pop(0)
|
||||
sys.argv.pop(1)
|
||||
else:
|
||||
sys.argv.pop(0)
|
||||
sys.stderr.write("Error: argument value required")
|
||||
sys.exit(1)
|
||||
elif sys.argv[0] == '--list':
|
||||
sys.argv.pop(0)
|
||||
for t in tests:
|
||||
print t
|
||||
sys.exit(0)
|
||||
elif sys.argv[0] == '--list-xml':
|
||||
sys.argv.pop(0)
|
||||
for t in tests:
|
||||
(mod,param) = t.split(None,2)
|
||||
tname = mod[4:mod.find(".py")] + "_" + \
|
||||
param[param.find("/")+1:param.find(".py")]
|
||||
c = ""
|
||||
if len(sys.argv):
|
||||
c = " ".join(sys.argv) + " "
|
||||
tcmd = PYTHON + ' run.py ' + c + t
|
||||
print '\t\t<Test name="%s" cmd="%s" wdir="tests/pjsua" />' % (tname, tcmd)
|
||||
sys.exit(0)
|
||||
elif sys.argv[0] == '-s' or sys.argv[0] == '--shell':
|
||||
if len(sys.argv) > 1:
|
||||
shell_cmd = sys.argv[1]
|
||||
sys.argv.pop(0)
|
||||
sys.argv.pop(1)
|
||||
else:
|
||||
sys.argv.pop(0)
|
||||
sys.stderr.write("Error: argument value required")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
# Generate arguments for run.py
|
||||
argv_st = " ".join(sys.argv)
|
||||
|
||||
# Init vars
|
||||
fails_cnt = 0
|
||||
tests_cnt = 0
|
||||
|
||||
# Re-create "logs" directory
|
||||
try:
|
||||
shutil.rmtree("logs")
|
||||
except:
|
||||
print "Warning: failed in removing directory 'logs'"
|
||||
|
||||
try:
|
||||
os.mkdir("logs")
|
||||
except:
|
||||
print "Warning: failed in creating directory 'logs'"
|
||||
|
||||
# Now run the tests
|
||||
total_cnt = len(tests)
|
||||
for t in tests:
|
||||
if resume_script!="" and t.find(resume_script)==-1:
|
||||
print "Skipping " + t +".."
|
||||
total_cnt = total_cnt - 1
|
||||
continue
|
||||
resume_script=""
|
||||
cmdline = "python run.py " + argv_st + t
|
||||
if shell_cmd:
|
||||
cmdline = "%s '%s'" % (shell_cmd, cmdline)
|
||||
t0 = time.time()
|
||||
msg = "Running %d/%d: %s..." % (tests_cnt+1, total_cnt, cmdline)
|
||||
sys.stdout.write(msg)
|
||||
sys.stdout.flush()
|
||||
ret = os.system(cmdline + " > output.log")
|
||||
t1 = time.time()
|
||||
if ret != 0:
|
||||
dur = int(t1 - t0)
|
||||
print " failed!! [" + str(dur) + "s]"
|
||||
logname = re.search(".*\s+(.*)", t).group(1)
|
||||
logname = re.sub("[\\\/]", "_", logname)
|
||||
logname = re.sub("\.py$", ".log", logname)
|
||||
logname = "logs/" + logname
|
||||
shutil.move("output.log", logname)
|
||||
print "Please see '" + logname + "' for the test log."
|
||||
fails_cnt += 1
|
||||
else:
|
||||
dur = int(t1 - t0)
|
||||
print " ok [" + str(dur) + "s]"
|
||||
tests_cnt += 1
|
||||
|
||||
if fails_cnt == 0:
|
||||
print "All " + str(tests_cnt) + " tests completed successfully"
|
||||
else:
|
||||
print str(tests_cnt) + " tests completed, " + str(fails_cnt) + " test(s) failed"
|
||||
|
12
res/pjproject/tests/pjsua/scripts-call/100_simplecall.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/100_simplecall.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Simple call
|
||||
test_param = TestParam(
|
||||
"Basic call",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_0_1.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_0_1.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param= TestParam(
|
||||
"Callee=no SRTP, caller=optional SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_0_3.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_0_3.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=no SRTP, caller=optional (with duplicated offer) SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=0 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_0.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_0.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional SRTP, caller=no SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_1.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_1.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional SRTP, caller=optional SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_2.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_2.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional SRTP, caller=mandatory SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_3.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_1_3.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional SRTP, caller=optional (with duplicated offer) SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_1.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_1.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Simple call
|
||||
test_param = TestParam(
|
||||
"Callee=mandatory SRTP, caller=optional SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_2.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_2.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=mandatory SRTP, caller=mandatory SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_3.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_2_3.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=mandatory SRTP, caller=optional (with duplicated offer) SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_0.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_0.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional (with duplicated offer) SRTP, caller=no SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=0 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_1.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_1.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional (with duplicated offer) SRTP, caller=optional SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=1 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_2.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_2.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional (with duplicated offer) SRTP, caller=mandatory SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=2 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_3.py
Normal file
11
res/pjproject/tests/pjsua/scripts-call/150_srtp_3_3.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
test_param = TestParam(
|
||||
"Callee=optional (with duplicated offer) SRTP, caller=optional (with duplicated offer) SRTP",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-srtp=3 --srtp-secure=0 --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/200_tcp.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/200_tcp.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# TCP call
|
||||
test_param = TestParam(
|
||||
"TCP transport",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --no-udp --max-calls=1", uri_param=";transport=tcp"),
|
||||
InstanceParam("caller", "--null-audio --no-udp --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/300_ice_0_1.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/300_ice_0_1.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# ICE mismatch
|
||||
test_param = TestParam(
|
||||
"Callee=no ICE, caller=use ICE",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --use-ice --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/300_ice_1_0.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/300_ice_1_0.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# ICE mismatch
|
||||
test_param = TestParam(
|
||||
"Callee=use ICE, caller=no ICE",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-ice --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/300_ice_1_1.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/300_ice_1_1.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# ICE mismatch
|
||||
test_param = TestParam(
|
||||
"Callee=use ICE, caller=use ICE",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-ice --max-calls=1", enable_buffer=True),
|
||||
InstanceParam("caller", "--null-audio --use-ice --max-calls=1", enable_buffer=True)
|
||||
]
|
||||
)
|
22
res/pjproject/tests/pjsua/scripts-call/301_ice_public_a.py
Normal file
22
res/pjproject/tests/pjsua/scripts-call/301_ice_public_a.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Note:
|
||||
# - need --dis-codec to make INVITE packet less than typical MTU
|
||||
uas_args = "--null-audio --id=\"<sip:test1@pjsip.org>\" --registrar=sip:sip.pjsip.org --username=test1 --password=test1 --realm=pjsip.org --proxy=\"sip:sip.pjsip.org;lr\" --rtp-port 0 --stun-srv stun.pjsip.org --use-ice --use-compact-form --max-calls 1 --dis-codec=i --dis-codec=s --dis-codec=g"
|
||||
|
||||
uac_args = "--null-audio --id=\"<sip:test2@pjsip.org>\" --registrar=sip:sip.pjsip.org --username=test2 --password=test2 --realm=pjsip.org --proxy=\"sip:sip.pjsip.org;lr\" --rtp-port 0 --stun-srv stun.pjsip.org --use-ice --use-compact-form --max-calls 1 --dis-codec=i --dis-codec=s --dis-codec=g"
|
||||
|
||||
test_param = TestParam(
|
||||
"ICE via public internet",
|
||||
[
|
||||
InstanceParam( "callee", uas_args,
|
||||
uri="<sip:test1@pjsip.org>",
|
||||
have_reg=True, have_publish=False),
|
||||
InstanceParam( "caller", uac_args,
|
||||
uri="<sip:test2@pjsip.org>",
|
||||
have_reg=True, have_publish=False),
|
||||
]
|
||||
)
|
||||
|
25
res/pjproject/tests/pjsua/scripts-call/301_ice_public_b.py
Normal file
25
res/pjproject/tests/pjsua/scripts-call/301_ice_public_b.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# This test:
|
||||
# to make call with ICE but without STUN.
|
||||
|
||||
# Note:
|
||||
# - need --dis-codec to make INVITE packet less than typical MTU
|
||||
uas_args = "--null-audio --id=\"<sip:test1@pjsip.org>\" --registrar=sip:sip.pjsip.org --username=test1 --password=test1 --realm=pjsip.org --proxy=\"sip:sip.pjsip.org;lr\" --rtp-port 0 --use-ice --use-compact-form --max-calls 1 --dis-codec=i --dis-codec=s --dis-codec=g --log-file callee.log"
|
||||
|
||||
uac_args = "--null-audio --id=\"<sip:test2@pjsip.org>\" --registrar=sip:sip.pjsip.org --username=test2 --password=test2 --realm=pjsip.org --proxy=\"sip:sip.pjsip.org;lr\" --rtp-port 0 --use-ice --use-compact-form --max-calls 1 --dis-codec=i --dis-codec=s --dis-codec=g --log-file caller.log"
|
||||
|
||||
test_param = TestParam(
|
||||
"ICE via public internet with no STUN",
|
||||
[
|
||||
InstanceParam( "callee", uas_args,
|
||||
uri="<sip:test1@pjsip.org>",
|
||||
have_reg=True, have_publish=False),
|
||||
InstanceParam( "caller", uac_args,
|
||||
uri="<sip:test2@pjsip.org>",
|
||||
have_reg=True, have_publish=False),
|
||||
]
|
||||
)
|
||||
|
12
res/pjproject/tests/pjsua/scripts-call/305_ice_comp_1_2.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/305_ice_comp_1_2.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Different number of ICE components
|
||||
test_param = TestParam(
|
||||
"Callee=use ICE, caller=use ICE",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-ice --max-calls=1 --ice-no-rtcp", enable_buffer=True),
|
||||
InstanceParam("caller", "--null-audio --use-ice --max-calls=1", enable_buffer=True)
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/305_ice_comp_2_1.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/305_ice_comp_2_1.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Different number of ICE components
|
||||
test_param = TestParam(
|
||||
"Callee=use ICE, caller=use ICE",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --use-ice --max-calls=1", enable_buffer=True),
|
||||
InstanceParam("caller", "--null-audio --use-ice --max-calls=1 --ice-no-rtcp", enable_buffer=True)
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/350_prack_a.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/350_prack_a.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# TCP call
|
||||
test_param = TestParam(
|
||||
"Callee requires PRACK",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1 --use-100rel"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/350_prack_b.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/350_prack_b.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# TCP call
|
||||
test_param = TestParam(
|
||||
"Caller requires PRACK",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1 --use-100rel")
|
||||
]
|
||||
)
|
12
res/pjproject/tests/pjsua/scripts-call/400_tel_uri.py
Normal file
12
res/pjproject/tests/pjsua/scripts-call/400_tel_uri.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Simple call
|
||||
test_param = TestParam(
|
||||
"tel: URI in From",
|
||||
[
|
||||
InstanceParam("callee", "--null-audio --max-calls=1 --id tel:+111"),
|
||||
InstanceParam("caller", "--null-audio --max-calls=1")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 16 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 16000 --play-file wavs/input.11.wav --rec-file wavs/tmp.16.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 22 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 22050 --play-file wavs/input.11.wav --rec-file wavs/tmp.22.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 32 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 32000 --play-file wavs/input.11.wav --rec-file wavs/tmp.32.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 44 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 44100 --play-file wavs/input.11.wav --rec-file wavs/tmp.44.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 48 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 48000 --play-file wavs/input.11.wav --rec-file wavs/tmp.48.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 11 KHZ to 8 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 8000 --play-file wavs/input.11.wav --rec-file wavs/tmp.8.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 11 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 11025 --play-file wavs/input.8.wav --rec-file wavs/tmp.11.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 16 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 16000 --play-file wavs/input.8.wav --rec-file wavs/tmp.16.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 22 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 22050 --play-file wavs/input.8.wav --rec-file wavs/tmp.22.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 32 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 32000 --play-file wavs/input.8.wav --rec-file wavs/tmp.32.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 44 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 44100 --play-file wavs/input.8.wav --rec-file wavs/tmp.44.wav")
|
||||
]
|
||||
)
|
@@ -0,0 +1,11 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# simple test
|
||||
test_param = TestParam(
|
||||
"Resample (large filter) 8 KHZ to 48 KHZ",
|
||||
[
|
||||
InstanceParam("endpt", "--null-audio --quality 10 --clock-rate 48000 --play-file wavs/input.8.wav --rec-file wavs/tmp.48.wav")
|
||||
]
|
||||
)
|
19
res/pjproject/tests/pjsua/scripts-pesq/100_defaults.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/100_defaults.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with default pjsua settings
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --play-file wavs/input.16.wav --no-vad"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --rec-file wavs/tmp.16.wav --clock-rate 16000 --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.8
|
18
res/pjproject/tests/pjsua/scripts-pesq/101_defaults.py
Normal file
18
res/pjproject/tests/pjsua/scripts-pesq/101_defaults.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with default pjsua settings
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --play-file wavs/input.16.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --rec-file wavs/tmp.16.wav --clock-rate 16000 --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = None
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g711a.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g711a.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with PCMA codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec PCMA",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec pcma --clock-rate 8000 --play-file wavs/input.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec pcma --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.5
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g711u.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g711u.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with PCMU codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec PCMU",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec pcmu --clock-rate 8000 --play-file wavs/input.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec pcmu --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.5
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g722.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_g722.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with G722 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec G722",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec g722 --clock-rate 16000 --play-file wavs/input.16.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec g722 --clock-rate 16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.7
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_gsm.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_gsm.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with GSM codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec GSM",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec gsm --clock-rate 8000 --play-file wavs/input.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec gsm --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.0
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_ilbc.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_ilbc.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with iLBC codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec iLBC",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec ilbc --clock-rate 8000 --play-file wavs/input.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec ilbc --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.0
|
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with L16/16000/1 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec L16/16000/1",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --play-file wavs/input.16.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.5
|
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with L16/16000/2 codec
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --play-file wavs/input.2.16.wav"),
|
||||
InstanceParam("UA2", "--null-audio --stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --rec-file wavs/tmp.2.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = None
|
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_l16_8000.py
Normal file
19
res/pjproject/tests/pjsua/scripts-pesq/200_codec_l16_8000.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with L16/8000/1 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec L16/8000/1",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --play-file wavs/input.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.5
|
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with L16/8000/2 codec
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --play-file wavs/input.2.8.wav"),
|
||||
InstanceParam("UA2", "--null-audio --stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --rec-file wavs/tmp.2.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = None
|
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with Speex/16000 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec Speex WB",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --clock-rate 16000 --add-codec speex/16000 --play-file wavs/input.16.wav --no-vad"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --clock-rate 16000 --add-codec speex/16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.8
|
@@ -0,0 +1,19 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
ADD_PARAM = ""
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
ADD_PARAM += "--null-audio"
|
||||
|
||||
# Call with Speex/8000 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec Speex NB",
|
||||
[
|
||||
InstanceParam("UA1", ADD_PARAM + " --max-calls=1 --add-codec speex/8000 --clock-rate 8000 --play-file wavs/input.8.wav --no-vad"),
|
||||
InstanceParam("UA2", "--null-audio --max-calls=1 --add-codec speex/8000 --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
pesq_threshold = 3.65
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g711a.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g711a.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with PCMA codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec PCMA (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec pcma --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec pcma --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.5
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g711u.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g711u.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with PCMU codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec PCMU (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec pcmu --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec pcmu --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.5
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g722.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_g722.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with G722 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec G722 (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec g722 --clock-rate 16000 --play-file wavs/input.16.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec g722 --clock-rate 16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.7
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_gsm.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_gsm.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with GSM codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec GSM (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec gsm --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec gsm --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.0
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_ilbc.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_ilbc.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with iLBC codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec iLBC (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec ilbc --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec ilbc --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.0
|
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with L16/16000/1 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec L16/16000/1 (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --play-file wavs/input.16.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec L16/16000/1 --clock-rate 16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.5
|
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with L16/16000/2 codec
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings",
|
||||
[
|
||||
InstanceParam("UA1", "--stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --play-file wavs/input.2.16.wav --null-audio"),
|
||||
InstanceParam("UA2", "--stereo --max-calls=1 --clock-rate 16000 --add-codec L16/16000/2 --rec-file wavs/tmp.2.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = None
|
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_l16_8000.py
Normal file
17
res/pjproject/tests/pjsua/scripts-pesq/201_codec_l16_8000.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with L16/8000/1 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec L16/8000/1 (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec L16/8000/1 --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.5
|
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with L16/8000/2 codec
|
||||
test_param = TestParam(
|
||||
"PESQ defaults pjsua settings",
|
||||
[
|
||||
InstanceParam("UA1", "--stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --play-file wavs/input.2.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--stereo --max-calls=1 --clock-rate 8000 --add-codec L16/8000/2 --rec-file wavs/tmp.2.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = None
|
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with Speex/16000 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec Speex WB (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --clock-rate 16000 --add-codec speex/16000 --play-file wavs/input.16.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --clock-rate 16000 --add-codec speex/16000 --rec-file wavs/tmp.16.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.7
|
@@ -0,0 +1,17 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Call with Speex/8000 codec
|
||||
test_param = TestParam(
|
||||
"PESQ codec Speex NB (RX side uses snd dev)",
|
||||
[
|
||||
InstanceParam("UA1", "--max-calls=1 --add-codec speex/8000 --clock-rate 8000 --play-file wavs/input.8.wav --null-audio"),
|
||||
InstanceParam("UA2", "--max-calls=1 --add-codec speex/8000 --clock-rate 8000 --rec-file wavs/tmp.8.wav --auto-answer 200")
|
||||
]
|
||||
)
|
||||
|
||||
if (HAS_SND_DEV == 0):
|
||||
test_param.skip = True
|
||||
|
||||
pesq_threshold = 3.0
|
12
res/pjproject/tests/pjsua/scripts-pres/100_peertopeer.py
Normal file
12
res/pjproject/tests/pjsua/scripts-pres/100_peertopeer.py
Normal file
@@ -0,0 +1,12 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Direct peer to peer presence
|
||||
test_param = TestParam(
|
||||
"Direct peer to peer presence",
|
||||
[
|
||||
InstanceParam("client1", "--null-audio"),
|
||||
InstanceParam("client2", "--null-audio")
|
||||
]
|
||||
)
|
35
res/pjproject/tests/pjsua/scripts-pres/200_publish.py
Normal file
35
res/pjproject/tests/pjsua/scripts-pres/200_publish.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# $Id$
|
||||
#
|
||||
from inc_cfg import *
|
||||
|
||||
# Basic registration
|
||||
test_param = TestParam(
|
||||
"Presence with PUBLISH",
|
||||
[
|
||||
InstanceParam( "ua1",
|
||||
"--null-audio"+
|
||||
" --id=\"<sip:test1@pjsip.org>\""+
|
||||
" --registrar=sip:sip.pjsip.org" +
|
||||
" --username=test1" +
|
||||
" --password=test1" +
|
||||
" --realm=*" +
|
||||
" --proxy=\"sip:sip.pjsip.org;lr\"" +
|
||||
" --publish",
|
||||
uri="<sip:test1@pjsip.org>",
|
||||
have_reg=True,
|
||||
have_publish=True),
|
||||
InstanceParam( "ua2",
|
||||
"--null-audio"+
|
||||
" --id=\"<sip:test2@pjsip.org>\""+
|
||||
" --registrar=sip:sip.pjsip.org" +
|
||||
" --username=test2" +
|
||||
" --password=test2" +
|
||||
" --realm=*" +
|
||||
" --proxy=\"sip:sip.pjsip.org;lr\"" +
|
||||
" --publish",
|
||||
uri="<sip:test2@pjsip.org>",
|
||||
have_reg=True,
|
||||
have_publish=True),
|
||||
]
|
||||
)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user