def runCode(self, code, interpreter="ipy.exe", insert_args=''): if interpreter == "ipy.exe": code = self.TEMPLATE % code self.write("test-code.py", code) process = Process() process.StartInfo.FileName = interpreter process.StartInfo.Arguments = "%s test-code.py" % insert_args process.StartInfo.WorkingDirectory = self.testDir process.StartInfo.UseShellExecute = False process.StartInfo.RedirectStandardOutput = process.StartInfo.RedirectStandardError = True process.Start() process.WaitForExit(600000) if not process.HasExited: process.Kill() output = process.StandardOutput.ReadToEnd() error = process.StandardError.ReadToEnd() return process.ExitCode, output, error
class Popen(object): def __init__(self, args, executable, stdin=None, stdout=None, stderr=None): self.p = Process() i = self.p.StartInfo i.UseShellExecute = False i.RedirectStandardInput = True i.RedirectStandardOutput = True i.RedirectStandardError = True i.FileName = executable args.pop(0) i.Arguments = " ".join(args) def communicate(self, stdinData=None): self.p.Start() stdin = self.p.StandardInput stdout = self.p.StandardOutput stderr = self.p.StandardError if stdinData is not None: stdin.AutoFlush = True stdin.Write(stdinData) stdin.Flush() # ? problem when we have input data only! stdoutData = stdout.ReadToEnd() stderrData = stderr.ReadToEnd() if not self.p.HasExited: self.p.Kill() stdin.Close() stdout.Close() stderr.Close() self.p.Close() return stdoutData, stderrData
class IronPythonInstance: """ Class to hold a single instance of the Iron Python interactive console for testing purposes, and direct input to and from the instance. Example usage: from sys import exec_prefix ip = IronPythonInstance(sys.executable, exec_prefix) AreEqual(ip.Start(), True) if ip.ExecuteLine("1+1") != "2": raise "Bad console!" else: print "Console passes sanity check." ip.End() """ def __init__(self, pathToBin, wkDir, *parms): self.proc = Process() self.proc.StartInfo.FileName = pathToBin self.proc.StartInfo.WorkingDirectory = wkDir self.proc.StartInfo.Arguments = " ".join(parms) self.proc.StartInfo.UseShellExecute = False self.proc.StartInfo.RedirectStandardOutput = True self.proc.StartInfo.RedirectStandardInput = True self.proc.StartInfo.RedirectStandardError = True def Start(self): if (not self.proc.Start()): return False else: self.reader = self.proc.StandardOutput self.reader2 = self.proc.StandardError self.writer = self.proc.StandardInput self.InitializeErrorWatcher() self.EatToPrompt() return True def StartAndRunToCompletion(self): if (not self.proc.Start()): return (False, None, None) else: self.reader = self.proc.StandardOutput self.reader2 = self.proc.StandardError self.writer = self.proc.StandardInput # This will hang if the output exceeds the buffer size output = self.reader.ReadToEnd() output2 = self.reader2.ReadToEnd() return (True, output, output2, self.proc.ExitCode) def EnsureInteractive(self): twoPlusTwoResult = self.ExecuteLine("2 + 2", True) if "4" <> twoPlusTwoResult: raise AssertionError, 'EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult # Note that the prompt text could occur in the middle of other output. # However, it is important to read all the output from the child process # to avoid deadlocks. Hence, we assume that ">>> " will only occur # as the prompt. def EatToPrompt(self, readError=False): result = self.EatToMarker(">>> ", readError) return result[0:-len(">>> ")] def EatToMarker(self, marker, readError=False): slurped = "" while not marker in slurped: nextChar = self.reader.Read() if nextChar == -1: raise ValueError("unexpected end of input after reading '%s'" % slurped) slurped += chr(nextChar) if slurped == '...': raise ValueError("found ... instead of %s, after reading %s" % (marker, slurped)) assert (slurped.endswith(marker)) if readError: # This should be returned as separate return values, instead of being appended together return self.ReadError() + slurped else: return slurped # Execute a single-line command, and return the output def ExecuteLine(self, line, readError=False): self.writer.Write(line + "\n") return self.EatToPrompt(readError).rstrip() def ExecuteAndExit(self, line): self.writer.Write(line + "\n") i = 0 while i < 40 and not self.proc.HasExited: Thread.CurrentThread.Join(100) i += 1 return self.proc.ExitCode # Submit one line of a multi-line command to the console. There can be # multiple calls to ExecutePartialLine before a final call to ExecuteLine def ExecutePartialLine(self, line): self.writer.Write(line + "\n") ch = self.reader.Read() if ch == -1 or chr(ch) <> '.': raise AssertionError, 'missing the first dot' ch = self.reader.Read() if ch == -1 or chr(ch) <> '.': raise AssertionError, 'missing the second dot' ch = self.reader.Read() if ch == -1 or chr(ch) <> '.': raise AssertionError, 'missing the third dot' ch = self.reader.Read() if ch == -1 or chr(ch) <> ' ': raise AssertionError, 'missing the last space char' def End(self): if 'writer' in dir(self) and 'Close' in dir(self.writer): self.writer.Close() try: if not self.proc.HasExited: self.proc.Kill() except: print 'Leaked ipy process could not kill!' # Functions for the remote console def EnsureInteractiveRemote(self, readError=True): """Sometimes remote output can become available after the prompt is printed locally.""" twoPlusTwoResult = self.ExecuteLine("2 + 2", readError) if "4" == twoPlusTwoResult: return if "" <> twoPlusTwoResult: raise AssertionError, 'EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult twoPlusTwoResult = self.EatToMarker("4\r\n") if "4\r\n" <> twoPlusTwoResult: raise AssertionError, 'EnsureInteractive failed. 2+2 returned ' + twoPlusTwoResult def ExecuteLineRemote(self, line, expectedOutputLines=1): """Sometimes remote output can become available after the prompt is printed locally.""" result = self.ExecuteLine(line) if "" <> result: return result for i in xrange(expectedOutputLines): output = self.EatToMarker("\r\n") if output == "": raise AssertionError, 'ExecuteLineRemote failed. Returned empty after %s. Error is %s' % ( result, self.ReadError()) result += output return result[0:-2] # Functions to read stderr def InitializeErrorWatcher(self): from System.Threading import Thread, ThreadStart import thread self.errorLock = thread.allocate_lock() self.errorString = "" th = Thread(ThreadStart(self.WatchErrorStream)) th.IsBackground = True th.Start() def WatchErrorStream(self): while True: nextChar = self.reader2.Read() if (nextChar == -1): break self.errorLock.acquire() self.errorString += chr(nextChar) self.errorLock.release() def GetUnreadError(self): self.errorLock.acquire() result = self.errorString self.errorString = "" self.errorLock.release() return result def ReadError(self): # For reading the error stream, there is no marker to know when to stop reading. # Instead, we keep reading from the error stream until there is no text written # to it for 1 second. from time import sleep result = self.GetUnreadError() prev = result while True: sleep(1) result += self.GetUnreadError() if (result == prev): break prev = result return result
from Maui.Core import App proc = Process() proc.StartInfo.FileName = sys.executable proc.StartInfo.WorkingDirectory = testpath.rowan_root + '\\Languages\\IronPython\\Tests' proc.StartInfo.Arguments = '-X:TabCompletion -X:AutoIndent -X:ColorfulConsole' proc.StartInfo.UseShellExecute = True proc.StartInfo.WindowStyle = ProcessWindowStyle.Normal proc.StartInfo.CreateNoWindow = False started = proc.Start() try: superConsole = App(proc.Id) except Exception as e: print "test_superconsole.py failed: cannot initialize App object (probably running as service, or in minimized remote window)" print "On VSLGO-MAUI machines close all remote desktop sessions using EXIT command on desktop!" proc.Kill() sys.exit(1) superConsole.SendKeys('from pretest import *{ENTER}') #------------------------------------------------------------------------------ #--Tests def test_newlines(): ''' Ensure empty lines do not break the console. ''' #test superConsole.SendKeys('outputRedirectStart{(}{)}{ENTER}') superConsole.SendKeys('{ENTER}') superConsole.SendKeys('None{ENTER}')
strInput = StringBuilder() #Setup/start process p = Process() p.StartInfo.FileName = "cmd.exe" p.StartInfo.CreateNoWindow = True p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardOutput = True p.StartInfo.RedirectStandardInput = True p.StartInfo.RedirectStandardError = True p.OutputDataReceived += DataReceivedEventHandler(CmdOutputDataHandler) p.ErrorDataReceived += DataReceivedEventHandler(CmdOutputDataHandler) p.Start() wtr.WriteLine("SPID: %s\nCPID: %s" % (Process.GetCurrentProcess().Id, p.Id)) p.BeginErrorReadLine() p.BeginOutputReadLine() while (not p.HasExited): try: strInput.Append.Overloads[str](rdr.ReadLine()) if strInput.ToString().ToLower() == "exit": p.Kill() Process.GetCurrentProcess().Kill() else: p.StandardInput.WriteLine(strInput) strInput.Remove(0, strInput.Length) except: break
#Setup/start process p = Process() p.StartInfo.FileName = "cmd.exe" p.StartInfo.CreateNoWindow = True p.StartInfo.UseShellExecute = False p.StartInfo.RedirectStandardOutput = True p.StartInfo.RedirectStandardInput = True p.StartInfo.RedirectStandardError = True p.OutputDataReceived += DataReceivedEventHandler(CmdOutputDataHandler) p.ErrorDataReceived += DataReceivedEventHandler(CmdOutputDataHandler) p.Start() pids = Encoding.ASCII.GetBytes("SPID: %s\nCPID: %s" % (Process.GetCurrentProcess().Id, p.Id)) client.Send(pids, len(pids)) p.BeginErrorReadLine() p.BeginOutputReadLine() #Recieve loop while (not p.HasExited): try: inp = Encoding.ASCII.GetString(client.Receive(ep)[0]) if inp.ToLower() == "exit": p.Kill() Process.GetCurrentProcess().Kill() else: p.StandardInput.WriteLine(inp) except: p.Kill() break
class DotnetProcess(base.Process): def __init__(self, command, arguments=None, env=None, stdout=None, stderr=None, redirect_output=True, working_dir=None): self._cmdline = _get_cmd(command, arguments) self._process = CSharpProcess() self._started = False start_info = self._process.StartInfo start_info.FileName = self._cmdline[0] start_info.Arguments = self._cmdline[1:] self._env = env start_info.CreateNoWindow = True if working_dir is not None: start_info.WorkingDirectory = working_dir self._stdout = os.path.abspath(stdout) if stdout else None self._stderr = os.path.abspath(stderr) if stderr else None self._redirect_output = (stdout or stderr or redirect_output) if self._redirect_output: start_info.UseShellExecute = False start_info.RedirectStandardInput = True start_info.RedirectStandardOutput = True start_info.RedirectStandardError = True self._process.OutputDataReceived += self._stdout_handler self._process.ErrorDataReceived += self._stderr_handler self._stdout_lock = threading.Lock() if self._stdout: if os.path.isfile(self._stdout): shell.remove(self._stdout) self._stdout_ostream = IO.FileStream(self._stdout, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read) self._stdout_istream = IO.FileStream(self._stdout, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.ReadWrite) self._stdout_writer = IO.StreamWriter(self._stdout_ostream) self._stdout_reader = IO.StreamReader(self._stdout_istream) else: self._stdout_buffer = b'' self._stderr_lock = threading.Lock() if self._stderr: if os.path.isfile(self._stderr): shell.remove(self._stderr) self._stderr_ostream = IO.FileStream(self._stderr, IO.FileMode.Append, IO.FileAccess.Write, IO.FileShare.Read) self._stderr_istream = IO.FileStream(self._stderr, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.ReadWrite) self._stderr_writer = IO.StreamWriter(self._stderr_ostream) self._stderr_reader = IO.StreamReader(self._stderr_istream) else: self._stderr_buffer = b'' else: start_info.UseShellExecute = True start_info.RedirectStandardInput = False start_info.RedirectStandardOutput = False start_info.RedirectStandardError = False self._pid = None self._immutable = None @classmethod def immutable(cls, pid, command): p = cls(command[0], command[1:]) p._pid = pid p._immutable = True return p def _stdout_handler(self, sender, outline): data = outline.Data if data is None: return with self._stdout_lock: if self._stdout: self._stdout_writer.WriteLine(data) self._stdout_writer.Flush() else: self._stdout_buffer += data def _stderr_handler(self, sender, outline): data = outline.Data if data is None: return with self._stderr_lock: if self._stderr: self._stderr_writer.WriteLine(data) self._stderr_writer.Flush() else: self._stderr_buffer += data @property def command(self): return self._cmdline[0] @property def arguments(self): return self._cmdline[1:] def start(self): if self._immutable: raise NotImplemented # Setup environment variables process_env = self._process.StartInfo.EnvironmentVariables for key, value in self._create_env(self._env).items(): process_env[six.text_type(key)] = six.text_type(value) self._process.Start() if self._redirect_output: self._process.BeginOutputReadLine() self._process.BeginErrorReadLine() self._started = True def kill(self): if self._immutable: kill(self.pid) elif self._started: self._process.Kill() self.wait() def wait(self, timeout=None): if self._immutable: raise NotImplemented if self._started: if timeout is not None: return self._process.WaitForExit(timeout) else: while self.is_running: time.sleep(1) return True return False @property def is_running(self): if self._immutable: raise NotImplemented return not self._process.HasExited if self._started else False @property def pid(self): return (self._pid if self._immutable else (self._process.Id if self._started else 0)) @property def exit_code(self): if self._immutable: raise NotImplemented if self._started and self._process.HasExited: return self._process.ExitCode return None def write(self, string): if self._immutable: raise NotImplemented if self._redirect_output: self._process.StandardInput.WriteLine(string) def read(self): if self._immutable: raise NotImplemented if self._redirect_output: with self._stdout_lock: if self._stdout: return self._stdout_reader.ReadToEnd() else: result = self._stdout_buffer self._stdout_buffer = b'' return result return b'' def eread(self): if self._immutable: raise NotImplemented if self._redirect_output: with self._stderr_lock: if self._stderr: return self._stderr_reader.ReadToEnd() else: result = self._stderr_buffer self._stderr_buffer = b'' return result return b''