def execute(command): if not is_windows(): p = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, preexec_fn=os.setsid) else: p = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stopped = False handler = signal.getsignal(signal.SIGINT) def new_handler(frame, signum): global stopped stopped = True os.killpg(os.getpgid(p.pid), signal.SIGINT) signal.signal(signal.SIGINT, new_handler) log = Logger( self.log_filename_suffix if self.log_filename_suffix is not None else str(self.n_executions), verbose) # To record the output of the solver self.last_log = log.log_file for line in p.stdout: if verbose == 2: sys.stdout.write(line) log.write(line) p.wait() p.terminate() log.close() signal.signal(signal.SIGINT, handler) # Reset the right SIGINT return log.read(), stopped
def _extract_code(function_name): index, frame_info = _extract_correct_frame( function_name) # getting the good frame if frame_info.filename == "<stdin>": # Console case if is_windows(): assert False, "Console mode is not available on Windows" lines = reversed( list( readline.get_history_item(i + 1) for i in range(readline.get_current_history_length()))) return browse_code_bottom_to_top(lines, function_name) # The index of the line in the stack of the inspector changes between python 3.7 and 3.8: # In 3.8 the index is the line where the function name appears # In 3.7 and lower versions, it is the line at the end of the function # So the algorithms are completely different frame_info = list(reversed(inspect.stack( context=2000)))[index] # TODO how to avoid this constant? if sys.version_info[ 1] >= 8 and function_name != "Var" and function_name != "VarArray": # why special cases for Var and VarArray? lines = list(frame_info.code_context[frame_info.index:]) return browse_code_top_to_bottom(lines, function_name) else: lines = reversed(frame_info.code_context[:frame_info.index + 1]) return browse_code_bottom_to_top(lines, function_name)
def diff_files(file1, file2, tmp): command = "diff " + file1 + " " + file2 with open(tmp, "wb") as out: subprocess.Popen(command.split(), stdout=out, stderr=None, shell=is_windows()).communicate() with open(tmp, "r") as out: lines = out.readlines() os.remove(tmp) return lines
def system_command(command, origin, target): assert command in {"mv", "cp"} print(os.getcwd()) if is_windows(): command = "move" if command == 'mv' else command command = "copy" if command == 'cp' else command print(command, origin, target) if not os.path.isfile(origin): warning("file not found: " + origin) exit(0) subprocess.call([command, origin, target], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=is_windows())
def load(self, *, mode=1): for model, data, variant, prs_py, prs_jv, special, dataSpecial, nameXML, options_py in self.instances: for python_exec in PYTHON_VERSIONS: assert self.dir_pbs_py, "Call the __init__() function of g6_testing (constructor) before execute()" assert self.dir_pbs_jv, "Call the __init__() function of g6_testing (constructor) before execute()" assert self.dir_xml_py, "Call the __init__() function of g6_testing (constructor) before execute()" self.name_xml = self.xml_name(model, data, variant, prs_py, prs_jv, nameXML) # name of the XML file that will be generated if os.path.isfile(self.xml_path_py()): os.remove(self.xml_path_py()) if os.path.isfile(self.xml_path_jv()): os.remove(self.xml_path_jv()) self.print_information(model, data, variant, prs_py, prs_jv, python_exec) self.execute_compiler("PyCSP", self._command_py(model, data, variant, prs_py if not prs_py or prs_py[-1] == 'y' else prs_py + ".py", options_py, python_exec[0])) if not os.path.isfile(self.name_xml): print(RED + "file not found " + self.name_xml + WHITE) continue shutil.move(self.name_xml, self.xml_path_py()) if mode == 1: # comparison with jv self.execute_compiler("JvCSP", self._command_jv(model, data, variant, prs_jv, special, dataSpecial)) if not is_windows(): self.xml_indent(self.name_xml) shutil.move(self.name_xml, self.xml_path_jv()) if not is_windows(): self.check() elif mode == 2: # comparison with recorded XCSP files # if not is_windows(): # shutil.copy(self.dir_xcsp + self.name_xml, self.xml_path_jv()) # we copy the xcsp file in the java dir to simulate a comparison with JvCSP print(" Comparing PyCSP outcome with the XCSP3 file stored in " + self.dir_xcsp) self.check(True) else: with open(self.xml_path_py(), "r") as f: for line in f.readlines(): print(COLOR_PY + line[0:-1]) # TODO replace rm -rf by os.remove() and check all system commands if not is_windows(): os.system("rm -rf *.*~") # for removing the temporary files
def check(self, xcsp=False): xml_to_compare = self.xml_path_xcsp() if xcsp else self.xml_path_jv() self.counters["total"] += 1 # LZMA decompress xml_lzma = None if os.path.isfile(xml_to_compare + ".lzma"): if is_windows(): print(" Not comparing because of LZMA on windows") return None xml_lzma = xml_to_compare + ".lzma" import lzma with lzma.open(xml_lzma) as f: data = f.read() fp = open(xml_to_compare, "wb") fp.write(data) fp.close() print("Decompress " + xml_lzma + " done.") # Show differences if not os.path.isfile(self.xml_path_py()) or not os.path.isfile(xml_to_compare): warning("at least 1 file not found among " + self.xml_path_py() + " and " + xml_to_compare) self.counters["err"] += 1 if waiting: input("Press Enter to continue...") else: lines = self.diff_files(self.xml_path_py(), xml_to_compare, self.tmpDiff) if len(lines) == 0: print(" => No difference for " + self.name_xml) else: print(" => Several differences (" + str(len(lines)) + ") in " + self.name_xml) self.counters["diff"] += 1 self.print_differences(lines, limit=20 if len(lines) > 200 else None, xcsp=xcsp) if waiting: input("Press Enter to continue...") # LZMA delete the decompress file if xml_lzma is not None: os.remove(xml_to_compare) # Count differences diff = (RED if self.counters["diff"] > 0 else GREEN) + str(self.counters["diff"]) err = (RED if self.counters["err"] > 0 else GREEN) + str(self.counters["err"]) print("\n" + WHITE_BOLD + "[Currently] " + diff + WHITE + " difference(s) on " + str( self.counters["total"]) + " test(s) (" + err + WHITE + " error(s))\n")
def execute_compiler(title, command): if len(sys.argv) == 2: if sys.argv[1] == "-choco": command += " -solver=[choco,limit=2s]" elif sys.argv[1] == "-ace": command += " -solver=[ace,limit=2s]" print(BLUE + "Command:" + WHITE, command) out, error = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=is_windows()).communicate() # print(title + " stdout:") print(out.decode('utf-8')) if error.decode('utf-8') != "": print(title + " stderr : ") print(error.decode('utf-8'))
def xml_indent(file): cmd = ["pycsp3" + os.sep + "libs" + os.sep + "xmlindent" + os.sep + "xmlindent", '-i', '2', '-w', file] print(cmd) out, error = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=is_windows()).communicate() if error.decode('utf-8') != "": print("XmlIndent stderr : ")
def run(xcsp, diff=None, same=None): global waiting global PYTHON_VERSIONS # Load parameters # TODO: regular expression for extracting the versions? mode = "-xcsp" for arg in sys.argv: if arg.startswith("-version"): PYTHON_VERSIONS = [python_exec.replace("[", "").replace("]", "") for python_exec in arg.split("=")[1].split(",")] if arg == "-xcsp" or arg == "-same" or arg == "-diff": mode = arg if arg == "-waiting": waiting = True # Get versions for i, python_exec in enumerate(PYTHON_VERSIONS): cmd = [python_exec, "--version"] out, _ = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=is_windows()).communicate() version = out.decode('utf-8').strip() PYTHON_VERSIONS[i] = (python_exec, version) # Launch the set of instances if mode == "-xcsp": xcsp.load(mode=2) elif mode == "-same": same.load() elif mode == "-diff": diff.load()
import inspect import sys from pycsp3.dashboard import options from pycsp3.tools.utilities import flatten, is_windows if not is_windows(): import readline fileToTrace = [ arg for arg in sys.argv if arg.endswith(".py") and "compiler.py" not in arg ] + ["<stdin>"] def _global_value_of(variable): stack = list(reversed(inspect.stack(context=1))) frames = [ frame for frame in stack for trace in fileToTrace if trace in frame.filename ] # frames = [frame for frame in stack if frame.filename in fileToTrace] if len(frames) == 0: return None globs = frames[0].frame.f_globals return str(globs[variable]) if variable in globs.keys() else None def is_comment_line(line): if not isinstance(line, str): return False line = line.strip()