diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-06-15 19:43:43 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-06-15 19:43:43 +0000 |
commit | 52147c5315e8922dd74eccc96aef9814c507a5ce (patch) | |
tree | 66899eb44c84f61d03e423f7589a6f2a3b7b0240 | |
parent | 5e535ba2d77e5fa029901d60ecfabadac0f35d61 (diff) |
Added presence pjsua unit tests
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2025 74dad513-b988-da41-8d7b-12977e46ad98
23 files changed, 747 insertions, 541 deletions
diff --git a/pjsip-apps/src/test-pjsua/inc_cfg.py b/pjsip-apps/src/test-pjsua/inc_cfg.py index 7859cd8e..531fd1cb 100644 --- a/pjsip-apps/src/test-pjsua/inc_cfg.py +++ b/pjsip-apps/src/test-pjsua/inc_cfg.py @@ -1,27 +1,83 @@ -# $Id:$
-
-DEFAULT_ECHO = True
-DEFAULT_TRACE = True
-
-# Individual pjsua config class
-class Config:
- # 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
- def __init__(self, arg, echo_enabled=DEFAULT_ECHO, trace_enabled=DEFAULT_TRACE):
- self.arg = arg
- self.echo_enabled = echo_enabled
- self.trace_enabled = trace_enabled
-
-# Call config class
-class CallConfig:
- # additional parameter to be added to target URI
- uri_param = ""
- def __init__(self, title, callee_cfg, caller_cfg):
- self.title = title
- self.callee_cfg = callee_cfg
- self.caller_cfg = caller_cfg
-
+# $Id:$ +import random + +DEFAULT_ECHO = True +DEFAULT_TRACE = True +DEFAULT_START_SIP_PORT = 50000 + +# 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 + 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): + # 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 not ("--publish" in self.arg): + self.arg = self.arg + " --publish" + self.echo_enabled = echo_enabled + self.trace_enabled = trace_enabled + + +############################################ +# Test parameter class +class TestParam: + title = "" + # params is list containing InstanceParams objects + inst_params = [] + # list of Expect instances, to be filled at run-time by + # the test program + process = [] + # the function for test body + test_func = None + def __init__( self, + title, # Test title + inst_params, # InstanceParam's as list + func=None): + self.title = title + self.inst_params = inst_params + self.test_func = func + + + diff --git a/pjsip-apps/src/test-pjsua/inc_const.py b/pjsip-apps/src/test-pjsua/inc_const.py index 8ce13f09..37c7e96a 100644 --- a/pjsip-apps/src/test-pjsua/inc_const.py +++ b/pjsip-apps/src/test-pjsua/inc_const.py @@ -1,49 +1,49 @@ -# $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 = "Media for call [0-9]+ is suspended.*hold"
-# Media call is active
-MEDIA_ACTIVE = "Media for call [0-9]+ is active"
-# RX_DTMF
-RX_DTMF = "Incoming DTMF on call [0-9]+: "
-
-##########################
-# 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"
-
-
+# $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 = "Media for call [0-9]+ is suspended.*hold" +# Media call is active +MEDIA_ACTIVE = "Media for call [0-9]+ is active" +# RX_DTMF +RX_DTMF = "Incoming DTMF on call [0-9]+: " + +########################## +# 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" + + diff --git a/pjsip-apps/src/test-pjsua/inc_param.py b/pjsip-apps/src/test-pjsua/inc_param.py deleted file mode 100644 index 2d5c8122..00000000 --- a/pjsip-apps/src/test-pjsua/inc_param.py +++ /dev/null @@ -1,46 +0,0 @@ -# $Id:$
-###########################################
-# pjsua instantiation parameter
-class Pjsua:
- # instance name
- name = ""
- # command line arguments. Default is empty.
- # sample:
- # args = "--null-audio --local-port 0"
- args = ""
- # list containing send/expect/title list. Default empty.
- # The inside list contains three items, all are optional:
- # - the command to be sent to pjsua menu
- # - the string to expect
- # - optional string to describe what this is doing
- # Sample of command list containing two list items:
- # cmds = [["sleep 50",""], ["q","", "quitting.."]]
- cmds = []
- # print out the stdout output of this pjsua?
- echo = False
- # print out commands interacting with this pjsua?
- trace = False
- def __init__(self, name, args="", echo=False, trace=False, cmds=[]):
- self.name = name
- self.args = args
- self.echo = echo
- self.trace = trace
- self.cmds = cmds
-
-############################################
-# Test parameter class
-class Test:
- title = ""
- # params is list containing Pjsua objects
- run = []
- # list of Expect instances, to be filled at run-time by
- # the test program
- process = []
- # the function for test body
- test_func = None
- def __init__(self, title, run, func=None):
- self.title = title
- self.run = run
- self.test_func = func
-
-
diff --git a/pjsip-apps/src/test-pjsua/mod_call.py b/pjsip-apps/src/test-pjsua/mod_call.py index 845ed8d7..ff41593f 100644 --- a/pjsip-apps/src/test-pjsua/mod_call.py +++ b/pjsip-apps/src/test-pjsua/mod_call.py @@ -1,151 +1,131 @@ -# $Id:$
-import time
-import imp
-import sys
-import inc_param as param
-import inc_const as const
-
-# Load configuration
-cfg_file = imp.load_source("cfg_file", sys.argv[2])
-
-# Test title
-title = cfg_file.config.title
-port1 = "9060"
-
-# First pjsua
-p1 = param.Pjsua(
- "callee",
- args = cfg_file.config.callee_cfg.arg + " --local-port="+port1,
- echo = cfg_file.config.callee_cfg.echo_enabled,
- trace = cfg_file.config.callee_cfg.trace_enabled
- )
-
-# Second pjsua, make call to the first one
-p2 = param.Pjsua(
- "caller",
- args = cfg_file.config.caller_cfg.arg + " --local-port=0",
- echo = cfg_file.config.caller_cfg.echo_enabled,
- trace = cfg_file.config.caller_cfg.trace_enabled
- )
-
-# Test body function
-def test_func(t):
- callee = t.process[0]
- caller = t.process[1]
-
- # Caller making call
- caller.send("m")
- caller.send("sip:localhost:" + port1 + cfg_file.config.uri_param)
- caller.expect(const.STATE_CALLING)
-
- # Callee answers with 200/OK
- time.sleep(1)
- callee.expect(const.EVENT_INCOMING_CALL)
- callee.send("a")
- callee.send("200")
-
- # Wait until call is connected in both endpoints
- time.sleep(1)
- if callee.expect(const.STATE_CONFIRMED, False)==None:
- raise TestError("Call failed")
- caller.expect(const.STATE_CONFIRMED)
-
- # Synchronize stdout
- caller.send("echo 1")
- caller.expect("echo 1")
- callee.send("echo 1")
- callee.expect("echo 1")
-
- # Test that media is okay (with RFC 2833 DTMF)
- time.sleep(2)
- caller.send("#")
- caller.send("1122")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "2")
- callee.expect(const.RX_DTMF + "2")
-
- # Hold call
- caller.send("H")
- caller.expect(const.MEDIA_HOLD)
- callee.expect(const.MEDIA_HOLD)
-
- # Release hold
- time.sleep(2)
- caller.send("v")
- caller.expect(const.MEDIA_ACTIVE)
- callee.expect(const.MEDIA_ACTIVE)
-
- # Synchronize stdout
- caller.send("echo 1")
- caller.expect("echo 1")
- callee.send("echo 1")
- callee.expect("echo 1")
-
- # Test that media is okay (with RFC 2833 DTMF)
- caller.send("#")
- caller.send("1122")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "2")
- callee.expect(const.RX_DTMF + "2")
-
- # Synchronize stdout
- caller.send("echo 1")
- caller.expect("echo 1")
- callee.send("echo 1")
- callee.expect("echo 1")
-
- # UPDATE (by caller)
- caller.send("U")
- caller.expect(const.MEDIA_ACTIVE)
- callee.expect(const.MEDIA_ACTIVE)
-
- # Synchronize stdout
- caller.send("echo 1")
- caller.expect("echo 1")
- callee.send("echo 1")
- callee.expect("echo 1")
-
- # Test that media is okay (with RFC 2833 DTMF)
- time.sleep(2)
- caller.send("#")
- caller.send("1122")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "2")
- callee.expect(const.RX_DTMF + "2")
-
- # UPDATE (by callee)
- callee.send("U")
- callee.expect(const.MEDIA_ACTIVE)
- caller.expect(const.MEDIA_ACTIVE)
-
- # Synchronize stdout
- caller.send("echo 1")
- caller.expect("echo 1")
- callee.send("echo 1")
- callee.expect("echo 1")
-
- # Test that media is okay (with RFC 2833 DTMF)
- time.sleep(2)
- caller.send("#")
- caller.send("1122")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "1")
- callee.expect(const.RX_DTMF + "2")
- callee.expect(const.RX_DTMF + "2")
-
- # Hangup call
- time.sleep(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 = param.Test(title, run=[p1, p2], func=test_func)
-
-
+# $Id:$ +import time +import imp +import sys +import inc_const as const + +# Load configuration +cfg_file = imp.load_source("cfg_file", sys.argv[2]) + + +# Test body function +def test_func(t): + callee = t.process[0] + caller = t.process[1] + + # Caller making call + caller.send("m") + caller.send(t.inst_params[0].uri) + caller.expect(const.STATE_CALLING) + + # Callee answers with 200/OK + time.sleep(1) + callee.expect(const.EVENT_INCOMING_CALL) + callee.send("a") + callee.send("200") + + # Wait until call is connected in both endpoints + time.sleep(1) + if callee.expect(const.STATE_CONFIRMED, False)==None: + raise TestError("Call failed") + caller.expect(const.STATE_CONFIRMED) + + # Synchronize stdout + caller.send("echo 1") + caller.expect("echo 1") + callee.send("echo 1") + callee.expect("echo 1") + + # Test that media is okay (with RFC 2833 DTMF) + time.sleep(2) + caller.send("#") + caller.send("1122") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "2") + callee.expect(const.RX_DTMF + "2") + + # Hold call + caller.send("H") + caller.expect(const.MEDIA_HOLD) + callee.expect(const.MEDIA_HOLD) + + # Release hold + time.sleep(2) + caller.send("v") + caller.expect(const.MEDIA_ACTIVE) + callee.expect(const.MEDIA_ACTIVE) + + # Synchronize stdout + caller.send("echo 1") + caller.expect("echo 1") + callee.send("echo 1") + callee.expect("echo 1") + + # Test that media is okay (with RFC 2833 DTMF) + caller.send("#") + caller.send("1122") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "2") + callee.expect(const.RX_DTMF + "2") + + # Synchronize stdout + caller.send("echo 1") + caller.expect("echo 1") + callee.send("echo 1") + callee.expect("echo 1") + + # UPDATE (by caller) + caller.send("U") + caller.expect(const.MEDIA_ACTIVE) + callee.expect(const.MEDIA_ACTIVE) + + # Synchronize stdout + caller.send("echo 1") + caller.expect("echo 1") + callee.send("echo 1") + callee.expect("echo 1") + + # Test that media is okay (with RFC 2833 DTMF) + time.sleep(2) + caller.send("#") + caller.send("1122") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "2") + callee.expect(const.RX_DTMF + "2") + + # UPDATE (by callee) + callee.send("U") + callee.expect(const.MEDIA_ACTIVE) + caller.expect(const.MEDIA_ACTIVE) + + # Synchronize stdout + caller.send("echo 1") + caller.expect("echo 1") + callee.send("echo 1") + callee.expect("echo 1") + + # Test that media is okay (with RFC 2833 DTMF) + time.sleep(2) + caller.send("#") + caller.send("1122") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "1") + callee.expect(const.RX_DTMF + "2") + callee.expect(const.RX_DTMF + "2") + + # Hangup call + time.sleep(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 + diff --git a/pjsip-apps/src/test-pjsua/mod_pres.py b/pjsip-apps/src/test-pjsua/mod_pres.py new file mode 100644 index 00000000..e3b996a8 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/mod_pres.py @@ -0,0 +1,124 @@ +# $Id:$ +import time +import imp +import sys +import inc_const as const + +# Load configuration +cfg_file = imp.load_source("cfg_file", sys.argv[2]) + + +# 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("1") + u1.send(im_text) + u2.expect(" is typing") + u2.expect("MESSAGE from.*"+im_text) + u1.expect(im_text+".*delivered successfully") + + # Synchronize stdout + u1.sync_stdout() + u2.sync_stdout() + + +# Here where it all comes together +test = cfg_file.test_param +test.test_func = test_func + diff --git a/pjsip-apps/src/test-pjsua/mod_run.py b/pjsip-apps/src/test-pjsua/mod_run.py index 34171e4e..379b4f26 100644 --- a/pjsip-apps/src/test-pjsua/mod_run.py +++ b/pjsip-apps/src/test-pjsua/mod_run.py @@ -1,19 +1,10 @@ -# $Id:$
-import imp
-import sys
-import inc_param as param
-
-
-# Read configuration
-cfg_file = imp.load_source("cfg_file", sys.argv[2])
-
-# Test title
-title = "Basic pjsua"
-
-# Param to spawn pjsua
-p1 = param.Pjsua("pjsua", args=cfg_file.config.arg,
- echo=cfg_file.config.echo_enabled,
- trace=cfg_file.config.trace_enabled)
-
-# Here where it all comes together
-test = param.Test(title, run=[p1])
+# $Id:$ +import imp +import sys + + +# Read configuration +cfg_file = imp.load_source("cfg_file", sys.argv[2]) + +# Here where it all comes together +test = cfg_file.test_param diff --git a/pjsip-apps/src/test-pjsua/run.py b/pjsip-apps/src/test-pjsua/run.py index e84de340..ecc872f5 100644 --- a/pjsip-apps/src/test-pjsua/run.py +++ b/pjsip-apps/src/test-pjsua/run.py @@ -1,156 +1,165 @@ -# $Id:$
-import sys
-import imp
-import re
-import subprocess
-import time
-
-import inc_param as param
-import inc_const as const
-
-# Defaults
-G_ECHO=True
-G_TRACE=False
-G_EXE="..\\..\\bin\\pjsua_vc6d.exe"
-
-###################################
-# TestError exception
-class TestError:
- desc = ""
- def __init__(self, desc):
- self.desc = desc
-
-###################################
-# Poor man's 'expect'-like class
-class Expect:
- proc = None
- echo = False
- trace_enabled = False
- name = ""
- rh = re.compile(const.DESTROYED)
- ra = re.compile(const.ASSERT, re.I)
- rr = re.compile(const.STDOUT_REFRESH)
- def __init__(self, name, exe, args="", echo=G_ECHO, trace_enabled=G_TRACE):
- self.name = name
- self.echo = echo
- self.trace_enabled = trace_enabled
- fullcmd = exe + " " + args + " --stdout-refresh=5 --stdout-refresh-text=" + const.STDOUT_REFRESH
- self.trace("Popen " + fullcmd)
- self.proc = subprocess.Popen(fullcmd, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
- def send(self, cmd):
- self.trace("send " + cmd)
- self.proc.stdin.writelines(cmd + "\n")
- def expect(self, pattern, raise_on_error=True):
- self.trace("expect " + pattern)
- r = re.compile(pattern, re.I)
- refresh_cnt = 0
- while True:
- line = self.proc.stdout.readline()
- if line == "":
- raise 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 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 TestError(self.name + ": Timeout expecting pattern: " + pattern)
- else:
- return None # timeout
- # Search for expected text
- if r.search(line) != None:
- return line
- def wait(self):
- self.trace("wait")
- self.proc.wait()
- def trace(self, s):
- if self.trace_enabled:
- print self.name + ": " + "====== " + s + " ======"
-
-#########################
-# Error handling
-def handle_error(errmsg, t):
- print "====== Caught error: " + errmsg + " ======"
- time.sleep(1)
- for p in t.process:
- p.send("q")
- p.expect(const.DESTROYED, False)
- p.wait()
- print "Test completed with error: " + errmsg
- sys.exit(1)
-
-
-#########################
-# MAIN
-
-if len(sys.argv)!=3:
- print "Usage: run.py MODULE CONFIG"
- print "Sample:"
- print " run.py mod_run.py scripts-run/100_simple.py"
- sys.exit(1)
-
-
-# Import the test script
-script = imp.load_source("script", sys.argv[1])
-
-# Validate
-if script.test == None:
- print "Error: no test defined"
- sys.exit(1)
-
-if len(script.test.run) == 0:
- print "Error: test doesn't contain pjsua run descriptions"
- sys.exit(1)
-
-# Instantiate pjsuas
-print "====== Running " + script.test.title + " ======"
-for run in script.test.run:
- try:
- p = Expect(run.name, G_EXE, args=run.args, echo=run.echo, trace_enabled=run.trace)
- # Wait until initialized
- p.expect(const.PROMPT)
- p.send("echo 1")
- p.send("echo 1")
- p.expect("echo 1")
- # add running instance
- script.test.process.append(p)
- # run initial script
- for cmd in run.cmds:
- if len(cmd) >= 3 and cmd[2]!="":
- print "====== " + cmd[2] + " ======"
- if len(cmd) >= 1 and cmd[0]!="":
- p.send(cmd[0])
- if len(cmd) >= 2 and cmd[1]!="":
- p.expect(cmd[1])
-
- except 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 TestError, e:
- handle_error(e.desc, script.test)
-
-# Shutdown all instances
-time.sleep(2)
-for p in script.test.process:
- p.send("q")
- time.sleep(0.5)
- p.expect(const.DESTROYED, False)
- p.wait()
-
-# Done
-print "Test " + script.test.title + " completed successfully"
-sys.exit(0)
-
+# $Id:$ +import sys +import imp +import re +import subprocess +import time + +import inc_const as const + +# Defaults +G_EXE="..\\..\\bin\\pjsua_vc6d.exe" + +################################### +# TestError exception +class TestError: + desc = "" + def __init__(self, desc): + self.desc = desc + +################################### +# 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) + 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 + self.trace("Popen " + fullcmd) + self.proc = subprocess.Popen(fullcmd, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) + def send(self, cmd): + self.trace("send " + cmd) + self.proc.stdin.writelines(cmd + "\n") + def expect(self, pattern, raise_on_error=True): + self.trace("expect " + pattern) + r = re.compile(pattern, re.I) + refresh_cnt = 0 + while True: + line = self.proc.stdout.readline() + if line == "": + raise 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 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 TestError(self.name + ": 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") + self.send("echo 1") + self.expect("echo 1") + + def wait(self): + self.trace("wait") + self.proc.wait() + def trace(self, s): + if self.trace_enabled: + print self.name + ": " + "====== " + s + " ======" + +######################### +# Error handling +def handle_error(errmsg, t): + print "====== Caught error: " + errmsg + " ======" + time.sleep(1) + for p in t.process: + p.send("q") + p.send("q") + p.expect(const.DESTROYED, False) + p.wait() + print "Test completed with error: " + errmsg + sys.exit(1) + + +######################### +# MAIN + +if len(sys.argv)!=3: + print "Usage: run.py MODULE CONFIG" + print "Sample:" + print " run.py mod_run.py scripts-run/100_simple.py" + sys.exit(1) + + +# Import the test script +script = imp.load_source("script", sys.argv[1]) + +# Validate +if script.test == None: + print "Error: no test defined" + sys.exit(1) + +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 + " ======" +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 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 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() + +# Done +print "Test " + script.test.title + " completed successfully" +sys.exit(0) + diff --git a/pjsip-apps/src/test-pjsua/runall.py b/pjsip-apps/src/test-pjsua/runall.py index 0ded114b..41656345 100644 --- a/pjsip-apps/src/test-pjsua/runall.py +++ b/pjsip-apps/src/test-pjsua/runall.py @@ -1,4 +1,4 @@ -# $Id:$ +# $Id$ import os import sys @@ -12,14 +12,18 @@ excluded_tests = [ "svn", "scripts-call/150_srtp_2_1", "scripts-call/300_ice_1_1"] -# Add all tests in "scripts-run" directory. +# Add basic tests for f in os.listdir("scripts-run"): tests.append("mod_run.py scripts-run/" + f) -# Add all tests in "scripts-call" directory. +# 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) + # Filter-out excluded tests for pat in excluded_tests: tests = [t for t in tests if t.find(pat)==-1] diff --git a/pjsip-apps/src/test-pjsua/scripts-call/100_simplecall.py b/pjsip-apps/src/test-pjsua/scripts-call/100_simplecall.py index 1bfb9602..517483be 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/100_simplecall.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/100_simplecall.py @@ -1,10 +1,12 @@ -# $Id:$
-#
-import inc_cfg
-
-# Simple call
-config = inc_cfg.CallConfig(
- title = "Basic call",
- callee_cfg = inc_cfg.Config(arg="--null-audio"),
- caller_cfg = inc_cfg.Config(arg="--null-audio")
- )
+# $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") + ] + ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_0_1.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_0_1.py index 69651c83..bf40f0b0 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_0_1.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_0_1.py @@ -1,10 +1,11 @@ -# $Id:$
-#
-import inc_cfg
-
-# Simple call
-config = inc_cfg.CallConfig(
- title = "Callee=no SRTP, caller=optional SRTP",
- callee_cfg = inc_cfg.Config(arg="--null-audio"),
- caller_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0")
- )
+# $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") + ] + ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_0.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_0.py index cd9d50bd..7fe8b61e 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_0.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_0.py @@ -1,10 +1,11 @@ -# $Id:$
-#
-import inc_cfg
-
-# Simple call
-config = inc_cfg.CallConfig(
- title = "Callee=optional SRTP, caller=no SRTP",
- callee_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0"),
- caller_cfg = inc_cfg.Config(arg="--null-audio")
- )
+# $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") + ] + ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_1.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_1.py index 2a8ece51..90915840 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_1.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_1.py @@ -1,10 +1,11 @@ -# $Id:$
-#
-import inc_cfg
-
-# Simple call
-config = inc_cfg.CallConfig(
- title = "Callee=optional SRTP, caller=optional SRTP",
- callee_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0"),
- caller_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0")
- )
+# $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") + ] + ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_2.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_2.py index 7752293b..03f58863 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_2.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_1_2.py @@ -1,10 +1,11 @@ # $Id$ # -import inc_cfg +from inc_cfg import * -# Simple call -config = inc_cfg.CallConfig( - title = "Callee=optional SRTP, caller=mandatory SRTP", - callee_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0"), - caller_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=2 --srtp-secure=0") +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") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_1.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_1.py index 8c46b939..16341ebe 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_1.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_1.py @@ -1,10 +1,12 @@ # $Id$ # -import inc_cfg +from inc_cfg import * # Simple call -config = inc_cfg.CallConfig( - title = "Callee=mandatory SRTP, caller=optional SRTP", - callee_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=2 --srtp-secure=0"), - caller_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=1 --srtp-secure=0") +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") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_2.py b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_2.py index b03978d9..9ec2ab69 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_2.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/150_srtp_2_2.py @@ -1,10 +1,11 @@ # $Id$ # -import inc_cfg +from inc_cfg import * -# Simple call -config = inc_cfg.CallConfig( - title = "Callee=mandatory SRTP, caller=mandatory SRTP", - callee_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=2 --srtp-secure=0"), - caller_cfg = inc_cfg.Config(arg="--null-audio --use-srtp=2 --srtp-secure=0") +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") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/200_tcp.py b/pjsip-apps/src/test-pjsua/scripts-call/200_tcp.py index 0c96c466..52b5f358 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/200_tcp.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/200_tcp.py @@ -1,11 +1,12 @@ # $Id$ # -import inc_cfg +from inc_cfg import * # TCP call -config = inc_cfg.CallConfig( - title = "TCP transport", - callee_cfg = inc_cfg.Config(arg="--null-audio --no-udp"), - caller_cfg = inc_cfg.Config(arg="--null-audio --no-udp") +test_param = TestParam( + "TCP transport", + [ + InstanceParam("callee", "--null-audio --no-udp", uri_param=";transport=tcp --max-calls=1"), + InstanceParam("caller", "--null-audio --no-udp --max-calls=1") + ] ) -config.uri_param = ";transport=tcp" diff --git a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_0_1.py b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_0_1.py index f95cba73..fb0b9def 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_0_1.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_0_1.py @@ -1,10 +1,12 @@ -# $Id:$ +# $Id$ # -import inc_cfg +from inc_cfg import * # ICE mismatch -config = inc_cfg.CallConfig( - title = "Callee=no ICE, caller=use ICE", - callee_cfg = inc_cfg.Config(arg="--null-audio"), - caller_cfg = inc_cfg.Config(arg="--null-audio --use-ice") +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") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_0.py b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_0.py index c4dbe9bd..ef800e7f 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_0.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_0.py @@ -1,10 +1,12 @@ -# $Id:$ +# $Id$ # -import inc_cfg - +from inc_cfg import * + # ICE mismatch -config = inc_cfg.CallConfig( - title = "Callee=use ICE, caller=no ICE", - callee_cfg = inc_cfg.Config(arg="--null-audio --use-ice"), - caller_cfg = inc_cfg.Config(arg="--null-audio") +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") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_1.py b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_1.py index 19a32322..0bf8cc15 100644 --- a/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_1.py +++ b/pjsip-apps/src/test-pjsua/scripts-call/300_ice_1_1.py @@ -1,10 +1,12 @@ -# $Id:$ +# $Id$ # -import inc_cfg +from inc_cfg import * # ICE mismatch -config = inc_cfg.CallConfig( - title = "Callee=use ICE, caller=use ICE", - callee_cfg = inc_cfg.Config(arg="--null-audio --use-ice"), - caller_cfg = inc_cfg.Config(arg="--null-audio --use-ice") +test_param = TestParam( + "Callee=use ICE, caller=use ICE", + [ + InstanceParam("callee", "--null-audio --use-ice --max-calls=1"), + InstanceParam("caller", "--null-audio --use-ice --max-calls=1") + ] ) diff --git a/pjsip-apps/src/test-pjsua/scripts-pres/100_peertopeer.py b/pjsip-apps/src/test-pjsua/scripts-pres/100_peertopeer.py new file mode 100644 index 00000000..10f71589 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pres/100_peertopeer.py @@ -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") + ] + ) diff --git a/pjsip-apps/src/test-pjsua/scripts-pres/200_publish.py b/pjsip-apps/src/test-pjsua/scripts-pres/200_publish.py new file mode 100644 index 00000000..f73ffa5d --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-pres/200_publish.py @@ -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), + ] + ) + diff --git a/pjsip-apps/src/test-pjsua/scripts-run/100_simple.py b/pjsip-apps/src/test-pjsua/scripts-run/100_simple.py index b0b96512..f1e13cfc 100644 --- a/pjsip-apps/src/test-pjsua/scripts-run/100_simple.py +++ b/pjsip-apps/src/test-pjsua/scripts-run/100_simple.py @@ -1,8 +1,13 @@ -# $Id:$
-#
-# Just about the simple pjsua command line parameter, which should
-# never fail in any circumstances
-import inc_cfg
-
-config = inc_cfg.Config(arg = "--null-audio --local-port 0 --rtp-port 0")
-
+# $Id:$ +# +# Just about the simple pjsua command line parameter, which should +# never fail in any circumstances +from inc_cfg import * + +test_param = TestParam( + "Basic run", + [ + InstanceParam("pjsua", "--null-audio --local-port 0 --rtp-port 0") + ] + ) + diff --git a/pjsip-apps/src/test-pjsua/scripts-run/200_register.py b/pjsip-apps/src/test-pjsua/scripts-run/200_register.py new file mode 100644 index 00000000..34f837c8 --- /dev/null +++ b/pjsip-apps/src/test-pjsua/scripts-run/200_register.py @@ -0,0 +1,20 @@ +# $Id:$ +# +from inc_cfg import * + +# Basic registration +test_param = TestParam( + "Basic registration", + [ + InstanceParam( "client", + "--null-audio"+ + " --id=<sip:test1@pjsip.org>"+ + " --registrar=sip:sip.pjsip.org" + + " --username=test1" + + " --password=test1" + + " --realm=*", + uri="sip:test1@pjsip.org", + have_reg=True), + ] + ) + |