From 52147c5315e8922dd74eccc96aef9814c507a5ce Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 15 Jun 2008 19:43:43 +0000 Subject: Added presence pjsua unit tests git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2025 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/src/test-pjsua/inc_cfg.py | 110 +++++-- pjsip-apps/src/test-pjsua/inc_const.py | 98 +++---- pjsip-apps/src/test-pjsua/inc_param.py | 46 --- pjsip-apps/src/test-pjsua/mod_call.py | 282 +++++++++--------- pjsip-apps/src/test-pjsua/mod_pres.py | 124 ++++++++ pjsip-apps/src/test-pjsua/mod_run.py | 29 +- pjsip-apps/src/test-pjsua/run.py | 321 +++++++++++---------- pjsip-apps/src/test-pjsua/runall.py | 10 +- .../src/test-pjsua/scripts-call/100_simplecall.py | 22 +- .../src/test-pjsua/scripts-call/150_srtp_0_1.py | 21 +- .../src/test-pjsua/scripts-call/150_srtp_1_0.py | 21 +- .../src/test-pjsua/scripts-call/150_srtp_1_1.py | 21 +- .../src/test-pjsua/scripts-call/150_srtp_1_2.py | 13 +- .../src/test-pjsua/scripts-call/150_srtp_2_1.py | 12 +- .../src/test-pjsua/scripts-call/150_srtp_2_2.py | 13 +- pjsip-apps/src/test-pjsua/scripts-call/200_tcp.py | 13 +- .../src/test-pjsua/scripts-call/300_ice_0_1.py | 14 +- .../src/test-pjsua/scripts-call/300_ice_1_0.py | 16 +- .../src/test-pjsua/scripts-call/300_ice_1_1.py | 14 +- .../src/test-pjsua/scripts-pres/100_peertopeer.py | 12 + .../src/test-pjsua/scripts-pres/200_publish.py | 35 +++ .../src/test-pjsua/scripts-run/100_simple.py | 21 +- .../src/test-pjsua/scripts-run/200_register.py | 20 ++ 23 files changed, 747 insertions(+), 541 deletions(-) delete mode 100644 pjsip-apps/src/test-pjsua/inc_param.py create mode 100644 pjsip-apps/src/test-pjsua/mod_pres.py create mode 100644 pjsip-apps/src/test-pjsua/scripts-pres/100_peertopeer.py create mode 100644 pjsip-apps/src/test-pjsua/scripts-pres/200_publish.py create mode 100644 pjsip-apps/src/test-pjsua/scripts-run/200_register.py (limited to 'pjsip-apps/src') 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="+ + " --registrar=sip:sip.pjsip.org" + + " --username=test1" + + " --password=test1" + + " --realm=*" + + " --proxy=sip:sip.pjsip.org;lr" + + " --publish", + uri="", + have_reg=True, + have_publish=True), + InstanceParam( "ua2", + "--null-audio"+ + " --id="+ + " --registrar=sip:sip.pjsip.org" + + " --username=test2" + + " --password=test2" + + " --realm=*" + + " --proxy=sip:sip.pjsip.org;lr" + + " --publish", + uri="", + 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="+ + " --registrar=sip:sip.pjsip.org" + + " --username=test1" + + " --password=test1" + + " --realm=*", + uri="sip:test1@pjsip.org", + have_reg=True), + ] + ) + -- cgit v1.2.3