# Path: Peach/agent.py
# class Monitor(object):
#     """
#     Extend from this to implement a Monitor.
#     Monitors are run by an Agent and must operate in an async manner.
#     Any blocking tasks must be performed in another thread.
# 
#     Agent: onTestStarting()
#     Agent: onTestFinished()
#     Agent: redoTest()
#     Agent: Sending redoTest result [False]
#     Agent: detectFault()
#     Agent: Detected fault!
#     Agent: Sending detectFault result [True]
#     Agent: getMonitorData()
#     Agent: onFault()
#     Agent: stopRun()
#     Agent: onShutdown()
#     """
# 
#     def __init__(self, args):
#         """
#         Arguments are supplied via the Peach XML file.
# 
#         @type	args: Dictionary
#         @param	args: Dictionary of parameters
#         """
#         self._name = None
# 
#     def OnTestStarting(self):
#         """Called right before start of test case or variation."""
#         pass
# 
#     def OnTestFinished(self):
#         """Called right after a test case or variation."""
#         pass
# 
#     def GetMonitorData(self):
#         """Get any monitored data from a test case."""
#         return None
# 
#     def RedoTest(self):
#         """Should the current test be re-performed."""
#         return False
# 
#     def DetectedFault(self):
#         """Check if a fault was detected."""
#         return False
# 
#     def OnFault(self):
#         """Called when a fault was detected."""
#         pass
# 
#     def OnShutdown(self):
#         """Called when Agent is shutting down, typically at end of a test run or when a Stop-Run occurs."""
#         pass
# 
#     def StopRun(self):
#         """Return True to force test run to fail. This should return True if an unrecoverable error occurs."""
#         return False
# 
#     def PublisherCall(self, method):
#         """Called when a call action is being performed.
#         Call actions are used to launch programs, this gives the monitor a chance to determine if it should be
#         running the program under a debugger instead. Note: This is a bit of a hack to get this working.
#         """
#         pass
# 
# def MonitorDebug(monitor, msg):
#     print("Monitor[%s]: %s" % (monitor, highlight.info(msg)))
# 
# Path: Peach/Engine/common.py
# class PeachException(HardException):
#     """
#     Peach exceptions are specialized hard exceptions.
#     The message contained in a PeachException is presentable to the user w/o any stack trace, etc.
#     Examples would be:
#         "Error: The DataModel element requires a name attribute."
#     """
#     def __init__(self, msg, module="Unknown"):
#         Exception.__init__(self, msg)
#         self.module = module
#         self.msg = msg


import os
import re
import sys
import time
import json
import shlex
import signal
import threading
    import Queue
    import queue
    import win32con
    import win32api
    import win32serviceutil
from subprocess import Popen, STDOUT, PIPE, check_output
    from win32process import *
from Peach.agent import Monitor, MonitorDebug
from Peach.Engine.common import PeachException
from Peach.Utilities.common import *
        self.pid = self.process = None
        self.console_log = self.crash_trace = []
        self.failure = False
        self.first_run = True

    def OnTestStarting(self):
        if not self._IsRunning():
            self._StartProcess()

    def _StartProcess(self):
        print("Command: {}".format(self.arguments))
        self.process = Popen(self.arguments, stderr=STDOUT, stdout=PIPE,
                             env=os.environ, bufsize=1, close_fds=isPosix())
        self.pid = self.process.pid

        def enqueue_output(out, queue):
            for line in iter(out.readline, ""):
                queue.put(line)
            out.close()

        self.terminal_queue = Queue.Queue()
        self.terminal_producer = threading.Thread(target=enqueue_output, args=(self.process.stdout, self.terminal_queue))
        self.terminal_consumer = threading.Thread(target=self._grab_sanitizer_trace)
        self.terminal_producer.setDaemon(True)
        self.terminal_consumer.setDaemon(True)
        self.terminal_producer.start()
        self.terminal_consumer.start()

    def _IsRunning(self):
        if self.process is None:

# Path: Peach/agent.py
# class Monitor(object):
#     """
#     Extend from this to implement a Monitor.
#     Monitors are run by an Agent and must operate in an async manner.
#     Any blocking tasks must be performed in another thread.
# 
#     Agent: onTestStarting()
#     Agent: onTestFinished()
#     Agent: redoTest()
#     Agent: Sending redoTest result [False]
#     Agent: detectFault()
#     Agent: Detected fault!
#     Agent: Sending detectFault result [True]
#     Agent: getMonitorData()
#     Agent: onFault()
#     Agent: stopRun()
#     Agent: onShutdown()
#     """
# 
#     def __init__(self, args):
#         """
#         Arguments are supplied via the Peach XML file.
# 
#         @type	args: Dictionary
#         @param	args: Dictionary of parameters
#         """
#         self._name = None
# 
#     def OnTestStarting(self):
#         """Called right before start of test case or variation."""
#         pass
# 
#     def OnTestFinished(self):
#         """Called right after a test case or variation."""
#         pass
# 
#     def GetMonitorData(self):
#         """Get any monitored data from a test case."""
#         return None
# 
#     def RedoTest(self):
#         """Should the current test be re-performed."""
#         return False
# 
#     def DetectedFault(self):
#         """Check if a fault was detected."""
#         return False
# 
#     def OnFault(self):
#         """Called when a fault was detected."""
#         pass
# 
#     def OnShutdown(self):
#         """Called when Agent is shutting down, typically at end of a test run or when a Stop-Run occurs."""
#         pass
# 
#     def StopRun(self):
#         """Return True to force test run to fail. This should return True if an unrecoverable error occurs."""
#         return False
# 
#     def PublisherCall(self, method):
#         """Called when a call action is being performed.
#         Call actions are used to launch programs, this gives the monitor a chance to determine if it should be
#         running the program under a debugger instead. Note: This is a bit of a hack to get this working.
#         """
#         pass
# 
# def MonitorDebug(monitor, msg):
#     print("Monitor[%s]: %s" % (monitor, highlight.info(msg)))
# 
# Path: Peach/Engine/common.py
# class PeachException(HardException):
#     """
#     Peach exceptions are specialized hard exceptions.
#     The message contained in a PeachException is presentable to the user w/o any stack trace, etc.
#     Examples would be:
#         "Error: The DataModel element requires a name attribute."
#     """
#     def __init__(self, msg, module="Unknown"):
#         Exception.__init__(self, msg)
#         self.module = module
#         self.msg = msg


# Path: Peach/Agent/process.py
import os
import re
import sys
import time
import json
import shlex
import signal
import threading
    import Queue
    import queue
    import win32con
    import win32api
    import win32serviceutil
from subprocess import Popen, STDOUT, PIPE, check_output
    from win32process import *
from Peach.agent import Monitor, MonitorDebug
from Peach.Engine.common import PeachException
from Peach.Utilities.common import *

        self.pid = self.process = None
        self.console_log = self.crash_trace = []
        self.failure = False
        self.first_run = True

    def OnTestStarting(self):
        if not self._IsRunning():
            self._StartProcess()

    def _StartProcess(self):
        print("Command: {}".format(self.arguments))
        self.process = Popen(self.arguments, stderr=STDOUT, stdout=PIPE,
                             env=os.environ, bufsize=1, close_fds=isPosix())
        self.pid = self.process.pid

        def enqueue_output(out, queue):
            for line in iter(out.readline, ""):
                queue.put(line)
            out.close()

        self.terminal_queue = Queue.Queue()
        self.terminal_producer = threading.Thread(target=enqueue_output, args=(self.process.stdout, self.terminal_queue))
        self.terminal_consumer = threading.Thread(target=self._grab_sanitizer_trace)
        self.terminal_producer.setDaemon(True)
        self.terminal_consumer.setDaemon(True)
        self.terminal_producer.start()
        self.terminal_consumer.start()

    def _IsRunning(self):
        if self.process is None:

            MonitorDebug(self._name, "IsRunning: False (self.process == None")