blob: 9026f4f8834fb0694a19d3e78a49b6686055ae0a [file] [log] [blame]
Benny Prijonof9bd1f22008-06-16 13:04:44 +00001# $Id$
Benny Prijonocc1ada52008-06-15 19:43:43 +00002import sys
3import imp
4import re
Benny Prijonof9bd1f22008-06-16 13:04:44 +00005import os
Benny Prijonocc1ada52008-06-15 19:43:43 +00006import subprocess
Benny Prijonof9bd1f22008-06-16 13:04:44 +00007import random
Benny Prijonocc1ada52008-06-15 19:43:43 +00008import time
9
10import inc_const as const
Benny Prijono7d578a72008-06-20 00:25:55 +000011from inc_cfg import *
Benny Prijonocc1ada52008-06-15 19:43:43 +000012
Benny Prijonof9bd1f22008-06-16 13:04:44 +000013# Get the pjsua executable name
14if sys.platform.find("win32")!=-1:
15 e = "../../bin/pjsua_vc6d.exe"
16 st1 = os.stat(e)
17 if st1 != None:
18 G_EXE = e
19 e = "../../bin/pjsua_vc6d.exe"
20 st2 = os.stat(e)
21 if st2 != None and st2.st_mtime > st1.st_mtime:
22 G_EXE = e
23 st1 = st2
24 if G_EXE=="":
25 print "Unable to find valid pjsua. Please build pjsip first"
26 sys.exit(1)
27 G_INUNIX = False
28else:
29 f = open("../../../build.mak", "r")
30 while True:
31 line = f.readline()
32 if not line:
33 break
34 if line.find("TARGET_NAME")!=-1:
35 print line
36 G_EXE="../../bin/pjsua-" + line.split(":= ")[1]
37 break
38 if G_EXE=="":
39 print "Unable to find ../../../build.mak. Please build pjsip first"
40 sys.exit(1)
41 G_INUNIX = True
42
43
44G_EXE = G_EXE.rstrip("\n\r \t")
Benny Prijonocc1ada52008-06-15 19:43:43 +000045
46###################################
Benny Prijonocc1ada52008-06-15 19:43:43 +000047# Poor man's 'expect'-like class
48class Expect:
49 proc = None
50 echo = False
51 trace_enabled = False
52 name = ""
53 inst_param = None
54 rh = re.compile(const.DESTROYED)
55 ra = re.compile(const.ASSERT, re.I)
56 rr = re.compile(const.STDOUT_REFRESH)
57 def __init__(self, inst_param):
58 self.inst_param = inst_param
59 self.name = inst_param.name
60 self.echo = inst_param.echo_enabled
61 self.trace_enabled = inst_param.trace_enabled
62 fullcmd = G_EXE + " " + inst_param.arg + " --stdout-refresh=5 --stdout-refresh-text=" + const.STDOUT_REFRESH
63 self.trace("Popen " + fullcmd)
Benny Prijonof9bd1f22008-06-16 13:04:44 +000064 self.proc = subprocess.Popen(fullcmd, shell=G_INUNIX, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
Benny Prijonocc1ada52008-06-15 19:43:43 +000065 def send(self, cmd):
66 self.trace("send " + cmd)
67 self.proc.stdin.writelines(cmd + "\n")
68 def expect(self, pattern, raise_on_error=True):
69 self.trace("expect " + pattern)
70 r = re.compile(pattern, re.I)
71 refresh_cnt = 0
72 while True:
73 line = self.proc.stdout.readline()
74 if line == "":
75 raise TestError(self.name + ": Premature EOF")
76 # Print the line if echo is ON
77 if self.echo:
78 print self.name + ": " + line,
79 # Trap assertion error
80 if self.ra.search(line) != None:
81 if raise_on_error:
82 raise TestError(self.name + ": " + line)
83 else:
84 return None
85 # Count stdout refresh text.
86 if self.rr.search(line) != None:
87 refresh_cnt = refresh_cnt+1
88 if refresh_cnt >= 6:
89 self.trace("Timed-out!")
90 if raise_on_error:
91 raise TestError(self.name + ": Timeout expecting pattern: " + pattern)
92 else:
93 return None # timeout
94 # Search for expected text
95 if r.search(line) != None:
96 return line
97
98 def sync_stdout(self):
99 self.trace("sync_stdout")
100 self.send("echo 1")
101 self.expect("echo 1")
102
103 def wait(self):
104 self.trace("wait")
105 self.proc.wait()
106 def trace(self, s):
107 if self.trace_enabled:
108 print self.name + ": " + "====== " + s + " ======"
109
110#########################
111# Error handling
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000112def handle_error(errmsg, t, close_processes = True):
Benny Prijonocc1ada52008-06-15 19:43:43 +0000113 print "====== Caught error: " + errmsg + " ======"
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000114 if (close_processes):
115 time.sleep(1)
116 for p in t.process:
117 p.send("q")
118 p.send("q")
119 p.expect(const.DESTROYED, False)
120 p.wait()
Benny Prijonocc1ada52008-06-15 19:43:43 +0000121 print "Test completed with error: " + errmsg
122 sys.exit(1)
123
124
125#########################
126# MAIN
127
128if len(sys.argv)!=3:
129 print "Usage: run.py MODULE CONFIG"
130 print "Sample:"
131 print " run.py mod_run.py scripts-run/100_simple.py"
132 sys.exit(1)
133
134
135# Import the test script
136script = imp.load_source("script", sys.argv[1])
137
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000138# Init random seed
139random.seed()
140
Benny Prijonocc1ada52008-06-15 19:43:43 +0000141# Validate
142if script.test == None:
143 print "Error: no test defined"
144 sys.exit(1)
145
146if len(script.test.inst_params) == 0:
147 print "Error: test doesn't contain pjsua run descriptions"
148 sys.exit(1)
149
150# Instantiate pjsuas
151print "====== Running " + script.test.title + " ======"
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000152print "Using " + G_EXE + " as pjsua executable"
153
Benny Prijonocc1ada52008-06-15 19:43:43 +0000154for inst_param in script.test.inst_params:
155 try:
156 # Create pjsua's Expect instance from the param
157 p = Expect(inst_param)
158 # Wait until registration completes
159 if inst_param.have_reg:
160 p.expect(inst_param.uri+".*registration success")
161 # Synchronize stdout
162 p.send("")
163 p.expect(const.PROMPT)
164 p.send("echo 1")
165 p.send("echo 1")
166 p.expect("echo 1")
167 # add running instance
168 script.test.process.append(p)
169
170 except TestError, e:
171 handle_error(e.desc, script.test)
172
173# Run the test function
174if script.test.test_func != None:
175 try:
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000176 script.test.test_func(script.test, script.test.user_data)
Benny Prijonocc1ada52008-06-15 19:43:43 +0000177 except TestError, e:
178 handle_error(e.desc, script.test)
179
180# Shutdown all instances
181time.sleep(2)
182for p in script.test.process:
183 # Unregister if we have_reg to make sure that next tests
184 # won't wail
185 if p.inst_param.have_reg:
186 p.send("ru")
187 p.expect(p.inst_param.uri+".*unregistration success")
188 p.send("q")
189 p.send("q")
190 time.sleep(0.5)
191 p.expect(const.DESTROYED, False)
192 p.wait()
193
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000194# Run the post test function
195if script.test.post_func != None:
196 try:
197 script.test.post_func(script.test, script.test.user_data)
198 except TestError, e:
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000199 handle_error(e.desc, script.test, False)
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000200
Benny Prijonocc1ada52008-06-15 19:43:43 +0000201# Done
202print "Test " + script.test.title + " completed successfully"
203sys.exit(0)
204