this repo has no description
1import timeit, re, sys, os 2import utils, json_config 3 4## TODO Keyline/value dictionaries: entries == json_config.s_CommentKey are ignored. Make it a parameter 5 6class Output: 7 def __init__( self ): 8 stdout = "" 9 stderr = "" 10 11def on_terminate(proc): 12 print("process {} terminated with exit code {}".format(proc, proc.returncode)) 13 14############################################################################################## 15###################### MZN instance execution + result parsing low-level ##################### 16############################################################################################## 17## runCmdCmdline using system(). Actually used for checking as well. 18## run the specified shell command string and return the time. 19## can add ulimit etc. 20## s1, s2: filenames for strout, stderr 21## dictCmd: commands for Win and non-Win 22## meml: list of 2 values, soft & hard limits as N bytes 23def runCmdCmdline( s_Cmd, s1, s2, dictCmd, timeo, bVerbose=False, meml=None ): 24 tm = timeit.default_timer() 25 setCmd = dictCmd["windows"] if "win" in sys.platform and "cygwin" not in sys.platform else dictCmd["non-windows"] 26 sCmd = setCmd["runVerbose" if bVerbose else "runSilent"].format(meml[1], timeo, s_Cmd, s1, s2) 27 print( "\n RUNNING:", sCmd ) 28 os.system(sCmd) 29 tm = timeit.default_timer() - tm 30 return tm 31 32 33## runCmd using psutils. Actually should be used for checking as well. 34## run the specified shell command string and return the popen result. 35## TODO catch intermediate solutions if needed 36## meml: list of 2 values, soft & hard limits as N bytes 37def runCmd( s_Cmd, b_Shell=False, timeo=None, meml=None ): 38 import psutil, shlex, subprocess, resource 39 if b_Shell: 40 l_Cmd = s_Cmd 41 else: 42 l_Cmd = shlex.split( s_Cmd ) 43 tm = timeit.default_timer() 44 ################# In the following, the subprocess.RUN method fails to kill shell calls on Linux 45 #try: 46 # completed = subprocess.run( l_Cmd, shell=b_Shell, 47 # universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=timeo ) 48 #except subprocess.TimeoutExpired as te: 49 # completed = te 50 ################# Using psutils 51 proc = psutil.Popen(l_Cmd, shell=b_Shell, 52 universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 53 if None!=meml: 54 if hasattr( psutil, 'RLIMIT_AS' ): ## TODO move into preexec_fn for parallel tests? 55 proc.rlimit( resource.RLIMIT_AS, ( meml[0]*1000, meml[1]*1000 ) ) 56 else: 57 print( " ... but the OS doesn't support RLIMIT_AS." ) 58 completed = Output() 59 try: 60 completed.stdout, completed.stderr = proc.communicate(timeout=timeo) 61 except subprocess.TimeoutExpired: 62 print ( " soft_kill. ", end='' ) 63 procs = psutil.Process().children(recursive=True) 64 for p in procs: 65 p.terminate() 66 try: 67 completed.stdout, completed.stderr = proc.communicate(timeout=1) 68 except subprocess.TimeoutExpired as te: 69 print ( " hard_kill. ", end='' ) 70 procs = psutil.Process().children(recursive=True) 71 for p in procs: 72 p.kill() 73 completed.stdout, completed.stderr = proc.communicate() 74 ### Clean up: (does psutil.Process.communicate() wait for all descendants?) ----------------------------------- 75 procs = psutil.Process().children(recursive=True) 76 for p in procs: 77 p.kill() 78 ### OR: even Queue? 79# with psutil.Popen(["ifconfig"], stdout=subprocess.PIPE) as proc: 80# log.write(proc.stdout.read()) 81# 82# procs = psutil.Process().children() 83# for p in procs: 84# p.terminate() 85# gone, still_alive = psutil.wait_procs(procs, timeout=3, callback=on_terminate) 86# for p in still_alive: 87# p.kill() 88 tm = timeit.default_timer() - tm 89 return completed, tm 90 91def parseStderr( f, result, mapKL, mapKV ): 92# result["ProbSense"] = None 93# result["TimeFlt"] = None 94 for line in f: 95 line = line.strip() 96 checkKeylines( line, mapKL, result ) 97 checkKeyvalues( line, mapKV, result ) 98 99## Puts feasible solutions into solList if it's not None 100def parseStdout( f, result, mapKL, mapKV, solList ): 101 l_SolLast = "" 102 n_SolStatus = 0 103 result["Number_Solutions"] = 0 104 for line in f: 105 line = line.rstrip() ## To remove \n and spaces on the right 106 res00 = {} ## A temporary to see if we get a feasible solution separator 107 checkKeylines( line, mapKL, res00 ) 108 utils.mergeDict( result, res00 ) 109 checkKeyvalues( line, mapKV, result ) 110 ## See if it's a solution status 111 if "Sol_Status" in res00: 112 if 1==res00[ "Sol_Status" ][0]: 113 result["Number_Solutions"] += 1 114## result["Solution_Last"] = l_SolLast ## Or save it? Need from a file then but might be great to have here 115 if None!=solList: 116 solList.append( l_SolLast ) 117 l_SolLast = "" ## Clean up 118 else: 119 l_SolLast += line 120 l_SolLast += '\n' 121 122## Check if any keylines of the given 2-level dictionary equal the given line 123## The 1st level gives variable name, 2nd level gives the line->value map 124def checkKeylines( line, dict2, result ): 125 assert dict==type(dict2) ## What if we use OrderedDict??? TODO 126 assert isinstance(result, dict) 127 for key in dict2: 128 if json_config.s_CommentKey!=key: 129 val1 = dict2[key] 130 assert dict==type(val1), "checkKeylines: key '%s': '%s'==type (%s)" % \ 131 ( key, type(val1), val1.__str__() ) 132 if line in val1: 133 result[ key ] = [ val1[ line ], line ] 134 135## Check if any search pattern of the given dict values is in the given line 136## The key gives variable name, value gives the line->value mapping 137def checkKeyvalues( line, dictVal, result ): 138 assert dict==type(dictVal) ## What if we use OrderedDict??? TODO 139 assert isinstance(result, dict) 140 for key in dictVal: 141 if json_config.s_CommentKey!=key: 142 paramArray = dictVal[ key ] 143 assert 3<=len( paramArray ), \ 144 "Key '%s': param list should have >=3 elements, now: %s" % (key, paramArray.__str__()) 145 if None!=re.search( paramArray[0], line ): 146 try: 147 lineSubst = re.sub( paramArray[1], ' ', line ) 148 except: 149 print(" WARNING: failed to substitute regex '", paramArray[1], 150 "' by ' ' in string '", line, "': ", sys.exc_info()[0:2] 151 , sep='') 152 else: 153 lSL = lineSubst.split() 154 if len( lSL )>paramArray[2]-1: 155 s_Val = lSL[ paramArray[2]-1 ] 156 ## d_Val = try_float( s_Val ) 157 result[key] = s_Val ### [ d_Val, s_Val ] Need here? 158## print( " checkKeyval: result[{}] = '{}'".format(key, s_Val) ) 159 else: 160 print( "ERROR: Parsing output line ", lSL, 161 ": regex key '", paramArray[0], 162 "' found, but the split line too short for index ", paramArray[2], 163 sep='' )