blob: ad038882d74ae10806d7ebd3562688bf6b7d1a35 [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 Prijono5242a422008-06-26 16:27:17 +000064 self.proc = subprocess.Popen(fullcmd, shell=G_INUNIX, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=False)
Benny Prijonocc1ada52008-06-15 19:43:43 +000065 def send(self, cmd):
66 self.trace("send " + cmd)
67 self.proc.stdin.writelines(cmd + "\n")
Benny Prijono5242a422008-06-26 16:27:17 +000068 self.proc.stdin.flush()
69 def expect(self, pattern, raise_on_error=True, title=""):
Benny Prijonocc1ada52008-06-15 19:43:43 +000070 self.trace("expect " + pattern)
71 r = re.compile(pattern, re.I)
72 refresh_cnt = 0
73 while True:
74 line = self.proc.stdout.readline()
75 if line == "":
76 raise TestError(self.name + ": Premature EOF")
77 # Print the line if echo is ON
78 if self.echo:
79 print self.name + ": " + line,
80 # Trap assertion error
81 if self.ra.search(line) != None:
82 if raise_on_error:
83 raise TestError(self.name + ": " + line)
84 else:
85 return None
86 # Count stdout refresh text.
87 if self.rr.search(line) != None:
88 refresh_cnt = refresh_cnt+1
89 if refresh_cnt >= 6:
90 self.trace("Timed-out!")
91 if raise_on_error:
Benny Prijono5242a422008-06-26 16:27:17 +000092 raise TestError(self.name + " " + title + ": Timeout expecting pattern: \"" + pattern + "\"")
Benny Prijonocc1ada52008-06-15 19:43:43 +000093 else:
94 return None # timeout
95 # Search for expected text
96 if r.search(line) != None:
97 return line
98
99 def sync_stdout(self):
100 self.trace("sync_stdout")
101 self.send("echo 1")
102 self.expect("echo 1")
103
104 def wait(self):
105 self.trace("wait")
106 self.proc.wait()
107 def trace(self, s):
108 if self.trace_enabled:
109 print self.name + ": " + "====== " + s + " ======"
110
111#########################
112# Error handling
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000113def handle_error(errmsg, t, close_processes = True):
Benny Prijonocc1ada52008-06-15 19:43:43 +0000114 print "====== Caught error: " + errmsg + " ======"
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000115 if (close_processes):
116 time.sleep(1)
117 for p in t.process:
118 p.send("q")
119 p.send("q")
120 p.expect(const.DESTROYED, False)
121 p.wait()
Benny Prijonocc1ada52008-06-15 19:43:43 +0000122 print "Test completed with error: " + errmsg
123 sys.exit(1)
124
125
126#########################
127# MAIN
128
129if len(sys.argv)!=3:
130 print "Usage: run.py MODULE CONFIG"
131 print "Sample:"
132 print " run.py mod_run.py scripts-run/100_simple.py"
133 sys.exit(1)
134
135
136# Import the test script
137script = imp.load_source("script", sys.argv[1])
138
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000139# Init random seed
140random.seed()
141
Benny Prijonocc1ada52008-06-15 19:43:43 +0000142# Validate
143if script.test == None:
144 print "Error: no test defined"
145 sys.exit(1)
146
Nanang Izzuddin6ee166d2008-06-26 12:26:52 +0000147if script.test.skip:
148 print "Test " + script.test.title + " is skipped"
149 sys.exit(0)
150
Benny Prijonocc1ada52008-06-15 19:43:43 +0000151if len(script.test.inst_params) == 0:
152 print "Error: test doesn't contain pjsua run descriptions"
153 sys.exit(1)
154
155# Instantiate pjsuas
156print "====== Running " + script.test.title + " ======"
Benny Prijonof9bd1f22008-06-16 13:04:44 +0000157print "Using " + G_EXE + " as pjsua executable"
158
Benny Prijonocc1ada52008-06-15 19:43:43 +0000159for inst_param in script.test.inst_params:
160 try:
161 # Create pjsua's Expect instance from the param
162 p = Expect(inst_param)
163 # Wait until registration completes
164 if inst_param.have_reg:
165 p.expect(inst_param.uri+".*registration success")
166 # Synchronize stdout
167 p.send("")
168 p.expect(const.PROMPT)
169 p.send("echo 1")
170 p.send("echo 1")
171 p.expect("echo 1")
172 # add running instance
173 script.test.process.append(p)
174
175 except TestError, e:
176 handle_error(e.desc, script.test)
177
178# Run the test function
179if script.test.test_func != None:
180 try:
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000181 script.test.test_func(script.test, script.test.user_data)
Benny Prijonocc1ada52008-06-15 19:43:43 +0000182 except TestError, e:
183 handle_error(e.desc, script.test)
184
185# Shutdown all instances
186time.sleep(2)
187for p in script.test.process:
188 # Unregister if we have_reg to make sure that next tests
189 # won't wail
190 if p.inst_param.have_reg:
191 p.send("ru")
192 p.expect(p.inst_param.uri+".*unregistration success")
193 p.send("q")
194 p.send("q")
195 time.sleep(0.5)
196 p.expect(const.DESTROYED, False)
197 p.wait()
198
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000199# Run the post test function
200if script.test.post_func != None:
201 try:
202 script.test.post_func(script.test, script.test.user_data)
203 except TestError, e:
Nanang Izzuddine6f85fb2008-06-20 17:43:55 +0000204 handle_error(e.desc, script.test, False)
Nanang Izzuddinf810f952008-06-18 21:04:14 +0000205
Benny Prijonocc1ada52008-06-15 19:43:43 +0000206# Done
207print "Test " + script.test.title + " completed successfully"
208sys.exit(0)
209