Changeset 5067


Ignore:
Timestamp:
Apr 13, 2015 12:28:02 PM (7 years ago)
Author:
nanang
Message:

Re #1842:

  • Updated python test driver run.py to perform stdout polling using a dedicated thread, this will increase the robustness of pattern matcing class "Expect" and remove the possibility of stucked pjsua (due to output buffer full when no stdout read polling is done).
  • Also updated other test driver and scenario accordingly.
Location:
pjproject/trunk/tests/pjsua
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/tests/pjsua/mod_sipp.py

    r4188 r5067  
    4141 
    4242# SIPp executable path and param 
    43 #SIPP_PATH = '"C:\\Program Files (x86)\\Sipp_3.2\\sipp.exe"' 
     43#SIPP_PATH = '"C:\\devs\\bin\\Sipp_3.2\\sipp.exe"' 
    4444SIPP_PATH = 'sipp' 
    4545SIPP_PORT    = 6000 
     
    225225    # Ideally the poll should be done contiunously until SIPp process is 
    226226    # terminated. 
    227     for ua_idx in range(len(ua)): 
    228         ua[ua_idx].expect(inc_const.STDOUT_REFRESH, raise_on_error = False) 
     227    # Update: now pjsua stdout is polled continuously by a dedicated thread, 
     228    #         so the poll is no longer needed 
     229    #for ua_idx in range(len(ua)): 
     230    #   ua[ua_idx].expect(inc_const.STDOUT_REFRESH, raise_on_error = False) 
    229231 
    230232    return ua_err_st 
  • pjproject/trunk/tests/pjsua/run.py

    r4183 r5067  
    77import random 
    88import time 
     9import threading 
     10import traceback 
    911import getopt 
    1012 
     
    110112################################### 
    111113# Poor man's 'expect'-like class 
    112 class Expect: 
     114class Expect(threading.Thread): 
    113115        proc = None 
    114116        echo = False 
    115117        trace_enabled = False 
    116         name = "" 
    117118        inst_param = None 
    118119        rh = re.compile(const.DESTROYED) 
     
    120121        rr = re.compile(const.STDOUT_REFRESH) 
    121122        t0 = time.time() 
     123        output = "" 
     124        lock = threading.Lock() 
     125        running = False 
    122126        def __init__(self, inst_param): 
     127                threading.Thread.__init__(self) 
    123128                self.inst_param = inst_param 
    124129                self.name = inst_param.name 
    125130                self.echo = inst_param.echo_enabled 
    126131                self.trace_enabled = inst_param.trace_enabled 
     132                 
     133        def run(self): 
    127134                fullcmd = G_EXE + " " + inst_param.arg + " --stdout-refresh=5 --stdout-refresh-text=" + const.STDOUT_REFRESH 
    128135                if not inst_param.enable_buffer: 
     
    130137                self.trace("Popen " + fullcmd) 
    131138                self.proc = subprocess.Popen(fullcmd, shell=G_INUNIX, bufsize=0, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=False) 
     139                self.running = True 
     140                while self.proc.poll() == None: 
     141                        line = self.proc.stdout.readline() 
     142                        if line == "": 
     143                                break; 
     144                                 
     145                        #Print the line if echo is ON 
     146                        if self.echo: 
     147                                print self.name + ": " + line.rstrip() 
     148 
     149                        self.lock.acquire() 
     150                        self.output += line 
     151                        self.lock.release() 
     152                self.running = False 
     153                                 
    132154        def send(self, cmd): 
    133155                self.trace("send " + cmd) 
    134156                self.proc.stdin.writelines(cmd + "\n") 
    135157                self.proc.stdin.flush() 
     158                 
    136159        def expect(self, pattern, raise_on_error=True, title=""): 
    137160                self.trace("expect " + pattern) 
    138161                r = re.compile(pattern, re.I) 
    139                 refresh_cnt = 0 
    140                 while True: 
    141                         line = self.proc.stdout.readline() 
    142                         if line == "": 
    143                                 raise inc.TestError(self.name + ": Premature EOF") 
    144                         # Print the line if echo is ON 
    145                         if self.echo: 
    146                                 print self.name + ": " + line.rstrip() 
    147                         # Trap assertion error 
    148                         if self.ra.search(line) != None: 
     162                found_at = -1 
     163                t0 = time.time() 
     164                while found_at < 0: 
     165                        self.lock.acquire() 
     166                        lines = self.output.splitlines() 
     167                         
     168                        for i, line in enumerate(lines): 
     169                                # Search for expected text 
     170                                if r.search(line) != None: 
     171                                        found_at = i 
     172                                        break 
     173                                 
     174                                # Trap assertion error 
    149175                                if raise_on_error: 
    150                                         raise inc.TestError(self.name + ": " + line) 
    151                                 else: 
    152                                         return None 
    153                         # Count stdout refresh text.  
    154                         if self.rr.search(line) != None: 
    155                                 refresh_cnt = refresh_cnt+1 
    156                                 if refresh_cnt >= 6: 
     176                                        if self.ra.search(line) != None: 
     177                                                self.lock.release() 
     178                                                raise inc.TestError(self.name + ": " + line) 
     179 
     180                        self.output = '\n'.join(lines[found_at+1:]) if found_at >= 0 else "" 
     181                        self.lock.release() 
     182                         
     183                        if found_at >= 0: 
     184                                return line 
     185 
     186                        if not self.running: 
     187                                if raise_on_error: 
     188                                        raise inc.TestError(self.name + ": Premature EOF") 
     189                                break 
     190                        else: 
     191                                t1 = time.time() 
     192                                dur = int(t1 - t0) 
     193                                if dur > 15: 
    157194                                        self.trace("Timed-out!") 
    158195                                        if raise_on_error: 
    159196                                                raise inc.TestError(self.name + " " + title + ": Timeout expecting pattern: \"" + pattern + "\"") 
    160                                         else: 
    161                                                 return None             # timeout 
    162                         # Search for expected text 
    163                         if r.search(line) != None: 
    164                                 return line 
     197                                        break 
     198                                else: 
     199                                        time.sleep(0.01) 
     200                return None 
     201                                                         
    165202 
    166203        def sync_stdout(self): 
     
    172209        def wait(self): 
    173210                self.trace("wait") 
     211                self.join() 
    174212                self.proc.communicate() 
    175213 
     
    207245                        else: 
    208246                                p.wait() 
     247                                 
    209248        print "Test completed with error: " + errmsg 
    210249        sys.exit(1) 
     
    241280                # Create pjsua's Expect instance from the param 
    242281                p = Expect(inst_param) 
     282                p.start() 
     283        except inc.TestError, e: 
     284                handle_error(e.desc, script.test) 
     285                 
     286        # wait process ready 
     287        while True: 
     288                try: 
     289                        p.send("echo 1") 
     290                except: 
     291                        time.sleep(0.1) 
     292                        continue 
     293                break 
     294 
     295        # add running instance 
     296        script.test.process.append(p) 
     297 
     298for p in script.test.process: 
     299        try: 
    243300                # Wait until registration completes 
    244                 if inst_param.have_reg: 
    245                         p.expect(inst_param.uri+".*registration success") 
     301                if p.inst_param.have_reg: 
     302                        p.expect(p.inst_param.uri+".*registration success") 
    246303                # Synchronize stdout 
    247304                p.send("") 
    248305                p.expect(const.PROMPT) 
    249306                p.send("echo 1") 
    250                 p.send("echo 1") 
    251307                p.expect("echo 1") 
    252                 # add running instance 
    253                 script.test.process.append(p) 
    254308 
    255309        except inc.TestError, e: 
     
    262316        except inc.TestError, e: 
    263317                handle_error(e.desc, script.test) 
     318        except: 
     319                handle_error("Unknown error: " + str(traceback.format_exc()), script.test) 
    264320 
    265321# Shutdown all instances 
    266 time.sleep(2) 
    267322for p in script.test.process: 
    268323        # Unregister if we have_reg to make sure that next tests 
     
    272327                p.expect(p.inst_param.uri+".*unregistration success") 
    273328        p.send("q") 
    274         p.send("q") 
    275         time.sleep(0.5) 
    276         p.expect(const.DESTROYED, False) 
     329 
     330time.sleep(0.5) 
     331for p in script.test.process: 
     332        if p.running: 
     333                p.expect(const.DESTROYED, False) 
    277334        p.wait() 
    278335 
  • pjproject/trunk/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.py

    r4373 r5067  
    66 
    77# Send hold after remote holds (double hold) 
    8 PJSUA_EXPECTS = [[0, const.MEDIA_HOLD, "H"]] 
     8PJSUA_EXPECTS = [[0, const.MEDIA_HOLD, ""], 
     9                 [0, "ACK sip:", "H"] 
     10                ] 
Note: See TracChangeset for help on using the changeset viewer.