blob: 74c028a9a6ad9e1959bb028f1f825428c9b816e5 [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
112def handle_error(errmsg, t):
113 print "====== Caught error: " + errmsg + " ======"
114 time.sleep(1)
115 for p in t.process:
116 p.send("q")
117 p.send("q")
118 p.expect(const.DESTROYED, False)
119 p.wait()
120 print "Test completed with error: " + errmsg
121 sys.exit(1)
122
123
124#########################
125# MAIN
126
127if len(sys.argv)!=3:
128 print "Usage: run.py MODULE CONFIG"
129 print "Sample:"
130 print " run.py mod_run.py scripts-run/100_simple.py"
131 sys.exit(1)
132
133
134# Import the test script
135script = imp.load_source("script", sys.argv[1])
136
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000137# Init random seed
138random.seed()
139
Benny Prijonocc1ada52008-06-15 19:43:43 +0000140# Validate
141if script.test == None:
142 print "Error: no test defined"
143 sys.exit(1)
144
145if len(script.test.inst_params) == 0:
146 print "Error: test doesn't contain pjsua run descriptions"
147 sys.exit(1)
148
149# Instantiate pjsuas
150print "====== Running " + script.test.title + " ======"
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000151print "Using " + G_EXE + " as pjsua executable"
152
Benny Prijonocc1ada52008-06-15 19:43:43 +0000153for inst_param in script.test.inst_params:
154 try:
155 # Create pjsua's Expect instance from the param
156 p = Expect(inst_param)
157 # Wait until registration completes
158 if inst_param.have_reg:
159 p.expect(inst_param.uri+".*registration success")
160 # Synchronize stdout
161 p.send("")
162 p.expect(const.PROMPT)
163 p.send("echo 1")
164 p.send("echo 1")
165 p.expect("echo 1")
166 # add running instance
167 script.test.process.append(p)
168
169 except TestError, e:
170 handle_error(e.desc, script.test)
171
172# Run the test function
173if script.test.test_func != None:
174 try:
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000175 script.test.test_func(script.test, script.test.user_data)
Benny Prijonocc1ada52008-06-15 19:43:43 +0000176 except TestError, e:
177 handle_error(e.desc, script.test)
178
179# Shutdown all instances
180time.sleep(2)
181for p in script.test.process:
182 # Unregister if we have_reg to make sure that next tests
183 # won't wail
184 if p.inst_param.have_reg:
185 p.send("ru")
186 p.expect(p.inst_param.uri+".*unregistration success")
187 p.send("q")
188 p.send("q")
189 time.sleep(0.5)
190 p.expect(const.DESTROYED, False)
191 p.wait()
192
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000193# Run the post test function
194if script.test.post_func != None:
195 try:
196 script.test.post_func(script.test, script.test.user_data)
197 except TestError, e:
198 handle_error(e.desc, script.test)
199
Benny Prijonocc1ada52008-06-15 19:43:43 +0000200# Done
201print "Test " + script.test.title + " completed successfully"
202sys.exit(0)
203