1
# $Id: run.py 3475 2011-03-23 03:48:13Z bennylp $
11
import inc_const as const
15
G_EXE = "" # pjsua executable path
16
G_INUNIX = False # flags that test is running in Unix
22
run.py - Automated test driver
25
run.py [options] MODULE CONFIG
27
--exe, -e pjsua executable path
28
--null-audio, -n use null audio
30
run.py -n mod_run.py scripts-run/100_simple.py
35
opts, args = getopt.getopt(sys.argv[1:], "hne:", ["help", "null-audio", "exe="])
36
except getopt.GetoptError, err:
41
if o in ("-h", "--help"):
44
elif o in ("-n", "--null-audio"):
46
elif o in ("-e", "--exe"):
49
print "Unknown options"
53
print "Invalid arguments"
57
# Set global ARGS to be used by modules
60
# Get the pjsua executable name
62
if sys.platform.find("win32")!=-1:
63
EXE_DIR = "../../pjsip-apps/bin/"
64
EXECUTABLES = [ "pjsua_vc6d.exe",
66
"pjsua-i386-Win32-vc8-Debug.exe",
67
"pjsua-i386-Win32-vc8-Debug-Dynamic.exe",
68
"pjsua-i386-Win32-vc8-Debug-Static.exe",
69
"pjsua-i386-Win32-vc8-Release.exe",
70
"pjsua-i386-Win32-vc8-Release-Dynamic.exe",
71
"pjsua-i386-Win32-vc8-Release-Static.exe"
76
if os.access(e, os.F_OK):
78
if e_ts==0 or e_ts<st.st_mtime:
83
print "Unable to find valid pjsua. Please build pjsip first"
88
f = open("../../build.mak", "r")
93
if line.find("TARGET_NAME")!=-1:
95
G_EXE="../../pjsip-apps/bin/pjsua-" + line.split(":= ")[1]
98
print "Unable to find ../../../build.mak. Please build pjsip first"
102
if sys.platform.lower().find("win32")!=-1 or sys.platform.lower().find("microsoft")!=-1:
108
G_EXE = G_EXE.rstrip("\n\r \t")
110
###################################
111
# Poor man's 'expect'-like class
115
trace_enabled = False
118
rh = re.compile(const.DESTROYED)
119
ra = re.compile(const.ASSERT, re.I)
120
rr = re.compile(const.STDOUT_REFRESH)
122
def __init__(self, inst_param):
123
self.inst_param = inst_param
124
self.name = inst_param.name
125
self.echo = inst_param.echo_enabled
126
self.trace_enabled = inst_param.trace_enabled
127
fullcmd = G_EXE + " " + inst_param.arg + " --stdout-refresh=5 --stdout-refresh-text=" + const.STDOUT_REFRESH
128
if not inst_param.enable_buffer:
129
fullcmd = fullcmd + " --stdout-no-buf"
130
self.trace("Popen " + fullcmd)
131
self.proc = subprocess.Popen(fullcmd, shell=G_INUNIX, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=False)
133
self.trace("send " + cmd)
134
self.proc.stdin.writelines(cmd + "\n")
135
self.proc.stdin.flush()
136
def expect(self, pattern, raise_on_error=True, title=""):
137
self.trace("expect " + pattern)
138
r = re.compile(pattern, re.I)
141
line = self.proc.stdout.readline()
143
raise inc.TestError(self.name + ": Premature EOF")
144
# Print the line if echo is ON
146
print self.name + ": " + line,
147
# Trap assertion error
148
if self.ra.search(line) != None:
150
raise inc.TestError(self.name + ": " + line)
153
# Count stdout refresh text.
154
if self.rr.search(line) != None:
155
refresh_cnt = refresh_cnt+1
157
self.trace("Timed-out!")
159
raise inc.TestError(self.name + " " + title + ": Timeout expecting pattern: \"" + pattern + "\"")
161
return None # timeout
162
# Search for expected text
163
if r.search(line) != None:
166
def sync_stdout(self):
167
self.trace("sync_stdout")
168
cmd = "echo 1" + str(random.randint(1000,9999))
174
self.proc.communicate()
177
if self.trace_enabled:
179
fmt = self.name + ": " + "================== " + s + " ==================" + " [at t=%(time)03d]"
180
print fmt % {'time':int(now - self.t0)}
182
#########################
184
def handle_error(errmsg, t, close_processes = True):
185
print "====== Caught error: " + errmsg + " ======"
186
if (close_processes):
189
# Protect against 'Broken pipe' exception
197
ret = p.expect(const.DESTROYED, False)
203
if sys.hexversion >= 0x02060000:
209
print "Test completed with error: " + errmsg
213
#########################
216
# Import the test script
217
script = imp.load_source("script", inc.ARGS[0])
223
if script.test == None:
224
print "Error: no test defined"
228
print "Test " + script.test.title + " is skipped"
231
if len(script.test.inst_params) == 0:
232
print "Error: test doesn't contain pjsua run descriptions"
236
print "====== Running " + script.test.title + " ======"
237
print "Using " + G_EXE + " as pjsua executable"
239
for inst_param in script.test.inst_params:
241
# Create pjsua's Expect instance from the param
242
p = Expect(inst_param)
243
# Wait until registration completes
244
if inst_param.have_reg:
245
p.expect(inst_param.uri+".*registration success")
248
p.expect(const.PROMPT)
252
# add running instance
253
script.test.process.append(p)
255
except inc.TestError, e:
256
handle_error(e.desc, script.test)
258
# Run the test function
259
if script.test.test_func != None:
261
script.test.test_func(script.test)
262
except inc.TestError, e:
263
handle_error(e.desc, script.test)
265
# Shutdown all instances
267
for p in script.test.process:
268
# Unregister if we have_reg to make sure that next tests
270
if p.inst_param.have_reg:
272
p.expect(p.inst_param.uri+".*unregistration success")
276
p.expect(const.DESTROYED, False)
279
# Run the post test function
280
if script.test.post_func != None:
282
script.test.post_func(script.test)
283
except inc.TestError, e:
284
handle_error(e.desc, script.test, False)
287
print "Test " + script.test.title + " completed successfully"